/*
 * Copyright © 2016-2017 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 RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
import showFileSaveDialog from 'nfvo-utils/ShowFileSaveDialog.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
import isEqual from 'lodash/isEqual.js';
import cloneDeep from 'lodash/cloneDeep.js';
import { actionTypes as modalActionTypes } from 'nfvo-components/modal/GlobalModalConstants.js';
import { modalContentMapper } from 'sdc-app/common/modal/ModalContentMapper.js';
import { actionTypes as softwareProductsActionTypes } from '../onboarding/softwareProduct/SoftwareProductConstants.js';
import { actionTypes as HeatSetupActions } from '../onboarding/softwareProduct/attachments/setup/HeatSetupConstants.js';

const options = {
    headers: {
        USER_ID: 'validationOnlyVspUser'
    }
};

function fetchVspIdAndVersion() {
    let vspId = sessionStorage.getItem('validationAppVspId');
    let versionId = sessionStorage.getItem('validationAppVersionId');
    if (vspId) {
        return Promise.resolve({ value: vspId, versionId });
    } else {
        return RestAPIUtil.fetch(
            '/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/validation-vsp',
            options
        ).then(response => {
            sessionStorage.setItem('validationAppVspId', response.itemId);
            sessionStorage.setItem(
                'validationAppVersionId',
                response.version.id
            );
            return Promise.resolve({
                value: response.itemId,
                versionId: response.version.id
            });
        });
    }
}

function uploadFile(formData) {
    return fetchVspIdAndVersion().then(response => {
        return RestAPIUtil.post(
            `/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${
                response.value
            }/versions/${response.versionId}/orchestration-template-candidate`,
            formData,
            options
        );
    });
}

function loadSoftwareProductHeatCandidate(dispatch) {
    return fetchVspIdAndVersion().then(response => {
        return RestAPIUtil.fetch(
            `/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${
                response.value
            }/versions/${
                response.versionId
            }/orchestration-template-candidate/manifest`,
            options
        ).then(response =>
            dispatch({
                type: HeatSetupActions.MANIFEST_LOADED,
                response
            })
        );
    });
}

function updateHeatCandidate(dispatch, heatCandidate) {
    return fetchVspIdAndVersion().then(response => {
        return RestAPIUtil.put(
            `/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${
                response.value
            }/versions/${
                response.versionId
            }/orchestration-template-candidate/manifest`,
            heatCandidate.heatData,
            options
        ).then(null, error => {
            dispatch({
                type: modalActionTypes.GLOBAL_MODAL_ERROR,
                data: {
                    title: i18n('Save Failed'),
                    modalComponentName:
                        modalContentMapper.SUMBIT_ERROR_RESPONSE,
                    modalComponentProps: {
                        validationResponse: error.responseJSON
                    },
                    cancelButtonText: i18n('Ok')
                }
            });
            return Promise.reject(error);
        });
    });
}

function fetchSoftwareProduct() {
    return fetchVspIdAndVersion().then(response => {
        return RestAPIUtil.fetch(
            `/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${
                response.value
            }/versions/${response.versionId}`,
            options
        );
    });
}

function downloadHeatFile() {
    return fetchVspIdAndVersion().then(response => {
        RestAPIUtil.fetch(
            `/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${
                response.value
            }/versions/${response.versionId}/orchestration-template-candidate`,
            {
                ...options,
                dataType: 'binary'
            }
        ).done(response =>
            showFileSaveDialog({
                blob: response.blob,
                headers: response.headers,
                defaultFilename: 'HEAT_file.zip',
                addTimestamp: true
            })
        );
    });
}

function processAndValidateHeatCandidate(dispatch) {
    return fetchVspIdAndVersion().then(response => {
        return RestAPIUtil.put(
            `/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${
                response.value
            }/versions/${
                response.versionId
            }/orchestration-template-candidate/process`,
            {},
            options
        ).then(response => {
            if (response.status === 'Success') {
                fetchSoftwareProduct().then(response => {
                    dispatch({
                        type:
                            softwareProductsActionTypes.SOFTWARE_PRODUCT_LOADED,
                        response
                    });
                });
            }
        });
    });
}

const UploadScreenActionHelper = {
    uploadFile(dispatch, formData) {
        return Promise.resolve()
            .then(() => uploadFile(formData))
            .then(response => {
                dispatch({
                    type: softwareProductsActionTypes.SOFTWARE_PRODUCT_LOADED,
                    response
                });
                dispatch({
                    type: HeatSetupActions.FILL_HEAT_SETUP_CACHE,
                    payload: {}
                });
                loadSoftwareProductHeatCandidate(dispatch);
            })
            .catch(error => {
                dispatch({
                    type: modalActionTypes.GLOBAL_MODAL_ERROR,
                    data: {
                        title: i18n('File Upload Failed'),
                        msg: error.responseJSON.message,
                        cancelButtonText: i18n('Ok')
                    }
                });
            });
    },

    processAndValidateHeat(dispatch, heatData, heatDataCache) {
        return isEqual(heatData, heatDataCache)
            ? Promise.resolve()
            : updateHeatCandidate(dispatch, heatData)
                  .then(() => processAndValidateHeatCandidate(dispatch))
                  .then(() =>
                      dispatch({
                          type: HeatSetupActions.FILL_HEAT_SETUP_CACHE,
                          payload: cloneDeep(heatData)
                      })
                  );
    },

    downloadHeatFile() {
        return downloadHeatFile();
    }
};

export default UploadScreenActionHelper;
