/*!
 * Copyright © 2016-2018 European Support Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
import deepFreeze from 'deep-freeze';
import pickBy from 'lodash/pickBy';
import mockRest from 'test-utils/MockRest.js';
import { cloneAndSet, buildListFromFactory } from 'test-utils/Util.js';
import { storeCreator } from 'sdc-app/AppStore.js';
import LicenseAgreementActionHelper from 'sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js';

import {
    LicenseAgreementStoreFactory,
    LicenseAgreementDispatchFactory,
    LicenseAgreementPostFactory,
    LicenseAgreementPutFactory
} from 'test-utils/factories/licenseModel/LicenseAgreementFactories.js';
import VersionFactory from 'test-utils/factories/common/VersionFactory.js';
import { SyncStates } from 'sdc-app/common/merge/MergeEditorConstants.js';
import CurrentScreenFactory from 'test-utils/factories/common/CurrentScreenFactory.js';

describe('License Agreement Module Tests', () => {
    const LICENSE_MODEL_ID = '777';
    const version = VersionFactory.build();
    const itemPermissionAndProps = CurrentScreenFactory.build({}, { version });
    const returnedVersionFields = {
        baseId: version.baseId,
        description: version.description,
        id: version.id,
        name: version.name,
        status: version.status
    };

    it('Load License Agreement List', () => {
        const licenseAgreementList = buildListFromFactory(
            LicenseAgreementStoreFactory
        );

        const store = storeCreator();
        deepFreeze(store.getState());

        const expectedStore = cloneAndSet(
            store.getState(),
            'licenseModel.licenseAgreement.licenseAgreementList',
            licenseAgreementList
        );

        mockRest.addHandler('fetch', ({ options, data, baseUrl }) => {
            expect(baseUrl).toEqual(
                `/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${
                    version.id
                }/license-agreements`
            );
            expect(data).toEqual(undefined);
            expect(options).toEqual(undefined);
            return { results: licenseAgreementList };
        });
        return LicenseAgreementActionHelper.fetchLicenseAgreementList(
            store.dispatch,
            { licenseModelId: LICENSE_MODEL_ID, version }
        ).then(() => {
            expect(store.getState()).toEqual(expectedStore);
        });
    });

    it('Delete License Agreement', () => {
        const licenseAgreementList = buildListFromFactory(
            LicenseAgreementStoreFactory,
            1
        );
        const store = storeCreator({
            currentScreen: { ...itemPermissionAndProps },
            licenseModel: {
                licenseAgreement: {
                    licenseAgreementList
                }
            }
        });
        deepFreeze(store.getState());
        const expectedCurrentScreenProps = {
            ...itemPermissionAndProps,
            itemPermission: {
                ...itemPermissionAndProps.itemPermission,
                isDirty: true
            }
        };
        const toBeDeletedLicenseAgreementId = licenseAgreementList[0].id;
        let expectedStore = cloneAndSet(
            store.getState(),
            'licenseModel.licenseAgreement.licenseAgreementList',
            []
        );
        expectedStore = cloneAndSet(
            expectedStore,
            'currentScreen.itemPermission',
            expectedCurrentScreenProps.itemPermission
        );

        mockRest.addHandler('destroy', ({ data, options, baseUrl }) => {
            expect(baseUrl).toEqual(
                `/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${
                    version.id
                }/license-agreements/${toBeDeletedLicenseAgreementId}`
            );
            expect(data).toEqual(undefined);
            expect(options).toEqual(undefined);
        });
        mockRest.addHandler('fetch', ({ data, options, baseUrl }) => {
            expect(baseUrl).toEqual(
                `/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${
                    version.id
                }`
            );
            expect(data).toEqual(undefined);
            expect(options).toEqual(undefined);
            return {
                ...returnedVersionFields,
                state: {
                    synchronizationState: SyncStates.UP_TO_DATE,
                    dirty: true
                }
            };
        });

        mockRest.addHandler('fetch', ({ data, options, baseUrl }) => {
            expect(baseUrl).toEqual(
                `/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}`
            );
            expect(data).toEqual(undefined);
            expect(options).toEqual(undefined);
            return {
                ...returnedVersionFields
            };
        });

        return LicenseAgreementActionHelper.deleteLicenseAgreement(
            store.dispatch,
            {
                licenseAgreementId: toBeDeletedLicenseAgreementId,
                licenseModelId: LICENSE_MODEL_ID,
                version
            }
        ).then(() => {
            expect(store.getState()).toEqual(expectedStore);
        });
    });

    it('Add License Agreement', () => {
        const store = storeCreator({
            currentScreen: { ...itemPermissionAndProps }
        });
        deepFreeze(store.getState());

        const licenseAgreementToAdd = LicenseAgreementDispatchFactory.build();

        const LicenseAgreementPostRequest = LicenseAgreementPostFactory.build(
            pickBy(
                licenseAgreementToAdd,
                (val, key) => key !== 'featureGroupsIds'
            )
        );

        deepFreeze(LicenseAgreementPostRequest);

        const licenseAgreementIdFromResponse = 'ADDED_ID';
        const licenseAgreementAfterAdd = LicenseAgreementStoreFactory.build({
            ...licenseAgreementToAdd,
            id: licenseAgreementIdFromResponse
        });
        deepFreeze(licenseAgreementAfterAdd);
        const licenseAgreementList = [licenseAgreementAfterAdd];
        const expectedCurrentScreenProps = {
            ...itemPermissionAndProps,
            itemPermission: {
                ...itemPermissionAndProps.itemPermission,
                isDirty: true
            }
        };
        const featureGroupsList = licenseAgreementList[0].featureGroupsIds;
        let expectedStore = cloneAndSet(
            store.getState(),
            'licenseModel.licenseAgreement.licenseAgreementList',
            [licenseAgreementAfterAdd]
        );
        expectedStore = cloneAndSet(
            expectedStore,
            'currentScreen.itemPermission',
            expectedCurrentScreenProps.itemPermission
        );

        mockRest.addHandler('post', ({ options, data, baseUrl }) => {
            expect(baseUrl).toEqual(
                `/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${
                    version.id
                }/license-agreements`
            );
            expect(data).toEqual(LicenseAgreementPostRequest);
            expect(options).toEqual(undefined);
            return {
                value: licenseAgreementIdFromResponse
            };
        });
        mockRest.addHandler('fetch', ({ options, data, baseUrl }) => {
            expect(baseUrl).toEqual(
                `/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${
                    version.id
                }/license-agreements`
            );
            expect(data).toEqual(undefined);
            expect(options).toEqual(undefined);
            return { results: licenseAgreementList };
        });
        mockRest.addHandler('fetch', ({ options, data, baseUrl }) => {
            expect(baseUrl).toEqual(
                `/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${
                    version.id
                }/feature-groups`
            );
            expect(data).toEqual(undefined);
            expect(options).toEqual(undefined);
            return { results: featureGroupsList };
        });
        mockRest.addHandler('fetch', ({ data, options, baseUrl }) => {
            expect(baseUrl).toEqual(
                `/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${
                    version.id
                }`
            );
            expect(data).toEqual(undefined);
            expect(options).toEqual(undefined);
            return {
                ...returnedVersionFields,
                state: {
                    synchronizationState: SyncStates.UP_TO_DATE,
                    dirty: true
                }
            };
        });

        mockRest.addHandler('fetch', ({ data, options, baseUrl }) => {
            expect(baseUrl).toEqual(
                `/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}`
            );
            expect(data).toEqual(undefined);
            expect(options).toEqual(undefined);
            return {
                ...returnedVersionFields
            };
        });

        return LicenseAgreementActionHelper.saveLicenseAgreement(
            store.dispatch,
            {
                licenseAgreement: licenseAgreementToAdd,
                licenseModelId: LICENSE_MODEL_ID,
                version
            }
        ).then(() => {
            expect(store.getState()).toEqual(expectedStore);
        });
    });

    it('Update License Agreement', () => {
        const licenseAgreementList = buildListFromFactory(
            LicenseAgreementStoreFactory,
            1,
            { featureGroupsIds: ['77'] }
        );
        const store = storeCreator({
            currentScreen: { ...itemPermissionAndProps },
            licenseModel: {
                licenseAgreement: {
                    licenseAgreementList
                }
            }
        });
        deepFreeze(store.getState());

        const previousLicenseAgreementData = licenseAgreementList[0];
        const toBeUpdatedLicenseAgreementId = previousLicenseAgreementData.id;
        const oldFeatureGroupIds =
            previousLicenseAgreementData.featureGroupsIds;

        const newFeatureGroupsIds = ['update_id_1', 'update_id_2'];

        const licenseAgreementUpdateData = LicenseAgreementStoreFactory.build({
            id: toBeUpdatedLicenseAgreementId,
            featureGroupsIds: newFeatureGroupsIds
        });
        deepFreeze(licenseAgreementUpdateData);

        const LicenseAgreementPutFactoryRequest = LicenseAgreementPutFactory.build(
            {
                addedFeatureGroupsIds: newFeatureGroupsIds,
                removedFeatureGroupsIds: oldFeatureGroupIds
            }
        );

        deepFreeze(LicenseAgreementPutFactoryRequest);

        const expectedCurrentScreenProps = {
            ...itemPermissionAndProps,
            itemPermission: {
                ...itemPermissionAndProps.itemPermission,
                isDirty: true
            }
        };
        let expectedStore = cloneAndSet(
            store.getState(),
            'licenseModel.licenseAgreement.licenseAgreementList',
            [licenseAgreementUpdateData]
        );
        expectedStore = cloneAndSet(
            expectedStore,
            'currentScreen.itemPermission',
            expectedCurrentScreenProps.itemPermission
        );

        mockRest.addHandler('put', ({ data, options, baseUrl }) => {
            expect(baseUrl).toEqual(
                `/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${
                    version.id
                }/license-agreements/${toBeUpdatedLicenseAgreementId}`
            );
            expect(data).toEqual(LicenseAgreementPutFactoryRequest);
            expect(options).toEqual(undefined);
        });
        mockRest.addHandler('fetch', ({ options, data, baseUrl }) => {
            expect(baseUrl).toEqual(
                `/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${
                    version.id
                }/license-agreements`
            );
            expect(data).toEqual(undefined);
            expect(options).toEqual(undefined);
            return { results: [licenseAgreementUpdateData] };
        });

        mockRest.addHandler('fetch', ({ options, data, baseUrl }) => {
            expect(baseUrl).toEqual(
                `/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${
                    version.id
                }/feature-groups`
            );
            expect(data).toEqual(undefined);
            expect(options).toEqual(undefined);
            return { results: [] };
        });

        mockRest.addHandler('fetch', ({ data, options, baseUrl }) => {
            expect(baseUrl).toEqual(
                `/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${
                    version.id
                }`
            );
            expect(data).toEqual(undefined);
            expect(options).toEqual(undefined);
            return {
                ...returnedVersionFields,
                state: {
                    synchronizationState: SyncStates.UP_TO_DATE,
                    dirty: true
                }
            };
        });

        mockRest.addHandler('fetch', ({ data, options, baseUrl }) => {
            expect(baseUrl).toEqual(
                `/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}`
            );
            expect(data).toEqual(undefined);
            expect(options).toEqual(undefined);
            return {
                ...returnedVersionFields
            };
        });

        return LicenseAgreementActionHelper.saveLicenseAgreement(
            store.dispatch,
            {
                licenseModelId: LICENSE_MODEL_ID,
                version,
                previousLicenseAgreement: previousLicenseAgreementData,
                licenseAgreement: licenseAgreementUpdateData
            }
        ).then(() => {
            expect(store.getState()).toEqual(expectedStore);
        });
    });
});
