/*
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you 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.
*/

const fs = require('fs-extra');
const path = require('path');
const events = require('cordova-common').events;
const { deepMerge } = require('./util');

const PLATFORM_MAPPING = {
    linux: 'linux',
    mac: 'darwin',
    windows: 'win32',
    win: 'win32'
};

const TARGET_TOP_LEVEL_KEY_MAPPING = {
    'nsis-web': 'nsisWeb'
};

class ElectronBuilder {
    constructor (buildOptions, api) {
        this.api = api;
        this.isDevelopment = buildOptions.debug;
        this.buildConfig = buildOptions && buildOptions.buildConfig && fs.existsSync(buildOptions.buildConfig) ? require(buildOptions.buildConfig) : false;
    }

    configure () {
        this.buildSettings = this.configureUserBuildSettings()
            .configureBuildSettings();

        // Replace the templated placeholders with the project defined settings into the buildSettings.
        this.injectProjectConfigToBuildSettings();

        return this;
    }

    configureUserBuildSettings () {
        if (this.buildConfig && this.buildConfig.electron) {
            let userBuildSettings = {};

            for (const platform in this.buildConfig.electron) {
                if (platform !== 'mac' && platform !== 'linux' && platform !== 'windows') continue;

                const platformConfigs = this.buildConfig.electron[platform];
                /**
                 * In this scenario, the user has added a valid platform to build for but has not provided any custom build configurations.
                 * This will fetch thew platform's default build configuration.
                 * Each platform's default build configurations are located in the "./build/" directory.
                 */
                if (Object.keys(platformConfigs).length === 0) {
                    userBuildSettings = deepMerge(userBuildSettings, this.fetchPlatformDefaults(PLATFORM_MAPPING[platform]));
                    continue;
                }

                /**
                 * Validate that the platform configuration properties provided are valid.
                 * Any invalid property will be warned and iggnored.
                 * If there is there are no valid properties
                 */
                if (!this.__validateUserPlatformBuildSettings(platformConfigs)) {
                    throw Error(`The platform "${platform}" contains an invalid property. Valid properties are: package, arch, signing`);
                }

                // Electron uses "win" as it's key, not "windows", so we will update here. We use windows in our settings for clarity.
                this.__formatAppendUserSettings(
                    (platform === 'windows' ? 'win' : platform),
                    platformConfigs,
                    userBuildSettings
                );

                this.___overridablePerPlatformOptions(
                    (platform === 'windows' ? 'win' : platform),
                    platformConfigs,
                    userBuildSettings
                );
            }

            this.userBuildSettings = userBuildSettings;
        }

        return this;
    }

    __formatAppendUserSettings (platform, platformConfigs, userBuildSettings) {
        // Add the platform at the root level to trigger build.
        userBuildSettings[platform] = [];

        // Add the config placeholder for build configurations (only add once if missing)
        if (!userBuildSettings.config) userBuildSettings.config = {};

        userBuildSettings.config[platform] = {
            target: []
        };

        // Apply custom app installer icon when the user is using a custom build configuration
        // eslint-disable-next-line no-template-curly-in-string
        userBuildSettings.config[platform].icon = '${APP_INSTALLER_ICON}';

        // Only macOS has a build type distinction. (development or distribution)
        // eslint-disable-next-line no-template-curly-in-string
        if (platform === 'mac') userBuildSettings.config[platform].type = '${BUILD_TYPE}';

        if (platformConfigs.package) {
            platformConfigs.package.forEach((target) => {
                if (target === 'mas') {
                    userBuildSettings.config.mas = {};
                }

                if (typeof target === 'object' && Object.keys(target).length !== 0) {
                    const targetKey = Object.keys(target)[0];
                    const rootKey = TARGET_TOP_LEVEL_KEY_MAPPING[targetKey] || targetKey;

                    userBuildSettings.config[rootKey] = target[targetKey];
                    target = targetKey;
                }

                /**
                 * The target of arch values are not validated as electron-builder will handle this.
                 * If the arch value is missing, 64-bit will be defaulted.
                 */
                userBuildSettings.config[platform].target.push({
                    target,
                    arch: platformConfigs.arch || ['x64']
                });
            });
        } else {
            /**
             * We will fetch and use the defaults when a package type is not identified.
             * If the arch value is identified, we will update each default package with the correct arch.
             */
            const platformDefaults = this.fetchPlatformDefaults(PLATFORM_MAPPING[platform]);
            const platformTargetPackages = platformDefaults.config[platform].target;

            if (platformConfigs.arch) {
                platformTargetPackages.forEach((pkg, i) => {
                    platformTargetPackages[i].arch = platformConfigs.arch;
                });
            }

            userBuildSettings.config[platform].target = platformTargetPackages;
        }

        if (platformConfigs.signing) {
            this.__appendUserSigning(platform, platformConfigs.signing, userBuildSettings);
        }
    }

    ___overridablePerPlatformOptions (platform, platformConfigs, userBuildSettings) {
        const PLATFORM_TOP_LEVEL_OPTIONS = {
            allPlatforms: [
                'appId',
                'artifactName',
                'asar',
                'compression',
                'detectUpdateChannel',
                'electronUpdaterCompatibility',
                'extraFiles',
                'extraResources',
                'fileAssociations',
                'files',
                'forceCodeSigning',
                'generateUpdatesFilesForAllChannels',
                'icon',
                'publish'
            ],
            linux: [
                'category',
                'description',
                'desktop',
                'executableName',
                'maintainer',
                'mimeTypes',
                'synopsis',
                'vendor'
            ],
            mac: [
                'binaries',
                'bundleShortVersion',
                'bundleVersion',
                'category',
                'darkModeSupport',
                'electronLanguages',
                'extendInfo',
                'extraDistFiles',
                'helperBundleId',
                'minimumSystemVersion'
            ],
            win: [
                'legalTrademarks',
                'publisherName',
                'requestedExecutionLevel',
                'rfc3161TimeStampServer',
                'signAndEditExecutable',
                'signDlls',
                'timeStampServer',
                'verifyUpdateCodeSignature'
            ]
        };

        for (const option in platformConfigs) {
            if (
                PLATFORM_TOP_LEVEL_OPTIONS.allPlatforms.includes(option) ||
                PLATFORM_TOP_LEVEL_OPTIONS[platform].includes(option)
            ) {
                userBuildSettings.config[platform][option] = platformConfigs[option];
            }
        }
    }

    __appendUserSigning (platform, signingConfigs, userBuildSettings) {
        if (platform === 'linux') {
            events.emit('warn', 'The provided signing information for the Linux platform is ignored. Linux does not support signing.');
            return this;
        }

        const config = this.isDevelopment ? signingConfigs.debug : signingConfigs.release;
        if (platform === 'mac' && config) {
            this.__appendMacUserSigning(config, userBuildSettings.config.mac);
        }

        const masConfig = this.isDevelopment ? null : (signingConfigs.store || null);
        if (platform === 'mac' && masConfig) {
            // Requirements is not available for mas.
            if (masConfig.requirements) delete masConfig.requirements;
            this.__appendMacUserSigning(masConfig, userBuildSettings.config.mas);
        }

        if (platform === 'win' && config) {
            this.__appendWindowsUserSigning(config, userBuildSettings.config.win);
        }
    }

    __validateUserPlatformBuildSettings (platformConfigs) {
        return !!(
            platformConfigs.package ||
            platformConfigs.arch ||
            platformConfigs.signing
        );
    }

    __appendMacUserSigning (config, buildConfigs) {
        if (config.identity || process.env.CSC_LINK || process.env.CSC_NAME) buildConfigs.identity = config.identity || process.env.CSC_LINK || process.env.CSC_NAME;

        const entitlements = config.entitlements;
        if (entitlements && fs.existsSync(entitlements)) {
            buildConfigs.entitlements = entitlements;
        } else if (entitlements) {
            events.emit('warn', `The provided entitlements file does not exist in the given path => ${entitlements}`);
        }

        const entitlementsInherit = config.entitlementsInherit;
        if (entitlementsInherit && fs.existsSync(entitlementsInherit)) {
            buildConfigs.entitlementsInherit = entitlementsInherit;
        } else if (entitlementsInherit) {
            events.emit('warn', `The provided entitlements inherit file does not exist in the given path => ${entitlementsInherit}`);
        }

        const requirements = config.requirements;
        if (requirements && fs.existsSync(requirements)) {
            buildConfigs.requirements = requirements;
        } else if (requirements) {
            events.emit('warn', `The provided requirements file does not exist in the given path => ${requirements}`);
        }

        const provisioningProfile = config.provisioningProfile;
        if (provisioningProfile && fs.existsSync(provisioningProfile)) {
            buildConfigs.provisioningProfile = provisioningProfile;
        } else if (provisioningProfile) {
            events.emit('warn', `The provided provisioning profile does not exist in the given path => ${provisioningProfile}`);
        }
    }

    __appendWindowsUserSigning (config, buildConfigs) {
        const certificateFile = config.certificateFile;
        if (certificateFile && fs.existsSync(certificateFile)) {
            buildConfigs.certificateFile = certificateFile;

            if (config.certificatePassword || process.env.CSC_KEY_PASSWORD) buildConfigs.certificatePassword = config.certificatePassword || process.env.CSC_KEY_PASSWORD;
        } else if (certificateFile) {
            events.emit('warn', `The provided certificate file does not exist in the given path => ${certificateFile}`);
        }

        if (config.certificateSubjectName) buildConfigs.certificateSubjectName = config.certificateSubjectName;
        if (config.certificateSha1) buildConfigs.certificateSha1 = config.certificateSha1;
        if (config.signingHashAlgorithms) buildConfigs.signingHashAlgorithms = config.signingHashAlgorithms;

        const additionalCertificateFile = config.additionalCertificateFile;
        if (additionalCertificateFile && fs.existsSync(additionalCertificateFile)) {
            buildConfigs.additionalCertificateFile = additionalCertificateFile;
        } else if (additionalCertificateFile) {
            events.emit('warn', `The provided addition certificate file does not exist in the given path => ${additionalCertificateFile}`);
        }
    }

    configureBuildSettings () {
        const baseConfig = require(path.resolve(__dirname, './build/base.json'));
        const platformConfig = this.userBuildSettings || this.fetchPlatformDefaults(process.platform);

        return deepMerge(baseConfig, platformConfig);
    }

    injectProjectConfigToBuildSettings () {
        // const isDevelopment = false;
        const packageJson = require(path.join(this.api.locations.www, 'package.json'));
        const userConfig = {
            APP_ID: packageJson.name,
            APP_TITLE: packageJson.displayName,
            APP_INSTALLER_ICON: 'installer.png',
            APP_BUILD_DIR: this.api.locations.build,
            APP_BUILD_RES_DIR: this.api.locations.buildRes,
            APP_WWW_DIR: this.api.locations.www,
            BUILD_TYPE: this.isDevelopment ? 'development' : 'distribution'
        };

        // convert to string for string replacement
        let buildSettingsString = JSON.stringify(this.buildSettings);

        Object.keys(userConfig).forEach((key) => {
            const regex = new RegExp(`\\$\\{${key}\\}`, 'g');
            const value = userConfig[key].replace(/\\/g, '\\\\');
            buildSettingsString = buildSettingsString.replace(regex, value);
        });

        // update build settings with formated data
        this.buildSettings = JSON.parse(buildSettingsString);

        return this;
    }

    fetchPlatformDefaults (platform) {
        const platformFile = path.resolve(__dirname, `./build/${platform}.json`);

        if (!fs.existsSync(platformFile)) {
            throw Error(`Your platform "${platform}" is not supported as a default target platform for Electron.`);
        }

        return require(platformFile);
    }

    build () {
        return require('electron-builder').build(this.buildSettings);
    }
}

module.exports.run = (buildOptions, api) => require('./check_reqs')
    .run()
    .then(() => (new ElectronBuilder(buildOptions, api))
        .configure()
        .build()
    )
    .catch(error => {
        throw error;
    });
