/*
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 apputil = require('./apputil');
const optimist = require('optimist');
const flagutil = require('./flagutil');
const repoutil = require('./repoutil');
const repoupdate = require('./repo-update');
const retrieveSha = require('./retrieve-sha');
const npmpublish = require('./npm-publish');
const versionutil = require('./versionutil');
const gitutil = require('./gitutil');
const fs = require('fs');
const path = require('path');
const repoclone = require('./repo-clone');

module.exports = function * (argv) {
    /** Specifies the default repos to build nightlies for */
    const DEFAULT_NIGHTLY_REPOS = ['cli', 'lib', 'fetch', 'common', 'create', 'coho'];

    let opt = flagutil.registerHelpFlag(optimist);
    opt = flagutil.registerRepoFlag(opt);

    argv = opt
        .usage('Publish CLI & LIB to NPM under nightly tag. \n' +
               'Cordova platform add uses latest commits to the platforms. \n' +
               'Usage: $0 nightly'
        )
        .options('pretend', {
            desc: 'Don\'t actually publish to npm, just print what would be run.',
            type: 'boolean'
        })
        .default({ r: DEFAULT_NIGHTLY_REPOS })
        .argv;

    if (argv.h) {
        optimist.showHelp();
        process.exit(1);
    }

    // Clone and update Repos
    yield prepareRepos(argv.r);

    const reposToBuild = flagutil.computeReposFromFlag(argv.r, { includeModules: true });
    // Get updated nightly versions for all repos
    /** @type {Object} A map of repo.id and a short SHA for every repo to build */
    const VERSIONS = yield retrieveVersions(reposToBuild);

    // Update version in package.json and other respective files for every repo
    // and update dependencies to use nightly versions of packages to be released
    yield repoutil.forEachRepo(reposToBuild, function * (repo) {
        apputil.print('Updating ' + repo.id + ' version to ' + VERSIONS[repo.id]);
        yield versionutil.updateRepoVersion(repo, VERSIONS[repo.id], { commitChanges: false });
        updateRepoDependencies(repo, VERSIONS);
    });

    // Pin nightly versions of platforms
    if (reposToBuild.some(function (repo) { return repo.id === 'lib'; })) {
        apputil.print('Updating platforms pinned versions...');
        versionutil.updatePlatformsConfig(VERSIONS);
    }

    const options = {};
    options.tag = 'nightly';
    options.pretend = argv.pretend;
    options.r = reposToBuild.map(function (repo) { return repo.id; });

    // publish to npm under nightly tag
    yield npmpublish.publishTag(options);
};

function * prepareRepos (repoNames) {
    // Clone and update required repos
    apputil.print('Cloning and updating required repositories...');
    const reposToClone = flagutil.computeReposFromFlag(['tools'].concat(repoNames));
    yield repoclone.cloneRepos(reposToClone, /* silent= */true);
    yield repoupdate.updateRepos(reposToClone, /* silent= */true);

    // Remove local changes and sync up with remote master
    apputil.print('Resetting repositories to "master" branches...');
    const reposToUpdate = flagutil.computeReposFromFlag(repoNames);
    yield repoutil.forEachRepo(reposToUpdate, function * () {
        yield gitutil.gitClean();
        yield gitutil.resetFromOrigin();
    });
}

/**
 * Updates current repo dependencies with versions, supplied in dependencies object
 * @param {Object} repo Current repo which dependencies need to be updated
 * @param {Object<String, String>} dependencies Map of package's id's and nightly versions
 */
function updateRepoDependencies (repo, dependencies) {
    const packageJSONPath = path.join(process.cwd(), 'package.json');
    const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath));

    // Let's iterate through repos we're going to release
    // eslint-disable-next-line array-callback-return
    Object.keys(dependencies).map(function (dependencyId) {
        const repo = repoutil.getRepoById(dependencyId);
        const packageId = repo.packageName || repo.repoName;

        if (packageJSON.dependencies[packageId]) {
            // If current repo has dependency that points to one of packages, we're going
            // to release, update that dependency's version to nightly
            apputil.print('Updating ' + packageId + ' dependency version to ' + dependencies[dependencyId]);
            packageJSON.dependencies[packageId] = dependencies[dependencyId];
        }
    });

    fs.writeFileSync(packageJSONPath, JSON.stringify(packageJSON, null, 2) + '\n', 'utf8');
}

/**
 * Generates suffix for appending to nightly package version
 *   based on current date and SHA string.
 * @param SHA {String} String to use to generate nightly version
 * @returns {String} A newly generated nightly suffix
 */
function getNightlySuffix (SHA) {
    const currentDate = new Date();
    // converts "2023-05-09T18:20:32.730Z" to "20230509182032730"
    const dateTime = currentDate.toISOString().replace(/[T|Z\-:.]/g, '');
    // @see https://semver.org/#spec-item-10
    // Example: -nightly+20230509182032730.sha.8d2286c9
    return `-nightly+${dateTime}.sha.${SHA}`;
}

/**
 * Generates map of repo.id -> nightly version based on current
 *   date and SHA of current revision of repository
 * @param {Object[]} repos An array of cordova repos
 * @returns {Object} Mapped object
 */
function * retrieveVersions (repos) {
    const SHAJSON = yield retrieveSha(repos);

    return Object.keys(SHAJSON).reduce(function (result, repoId) {
        const repoPath = repoutil.getRepoDir(repoutil.getRepoById(repoId));
        const oldVersion = require(path.join(repoPath, 'package.json')).version;
        result[repoId] = versionutil.removeDev(oldVersion) + getNightlySuffix(SHAJSON[repoId]);
        return result;
    }, {});
}
