'use strict';

// GLOBAL
const path = require('path');

// LOCAL
const tools = require('../../../scripts/utils/tools');
const configUtils = require('../config/config-utils');
const initUtils = require('../init/init-utils');

// CONSTANTS
const constants = require('./constants');


const replaceExtensions = (targetPath) => {
  return Promise.resolve()

    .then(() => {
      tools.logInfo('Executing post generation operations');
      if (tools.isFileExists(path.join(targetPath, 'gitignore_TO_REPLACE'))) {
        tools.move(path.join(targetPath, 'gitignore_TO_REPLACE'), path.join(targetPath, '.gitignore'));
      }
      if (tools.isFileExists(path.join(targetPath, 'package.json_TO_REPLACE'))) {
        tools.move(path.join(targetPath, 'package.json_TO_REPLACE'), path.join(targetPath, 'package.json'));
      }
    })
    .then(() => {
      tools.logInfo('Replace extensions');
      return tools.removeFilesExtension(targetPath, '.TO_REPLACE');
    })

    .catch((e) => {
      throw e;
    })
}

const replaceContent = (targetPath, name, scope, fullName) => {
  tools.replaceInPath(targetPath, '@module.name@', name);
  tools.replaceInPath(targetPath, '@module.full.name@', fullName);
  tools.replaceInPath(targetPath, '@module.scope@', scope);
  tools.replaceInPath(targetPath, '@module.scope-name@', `${scope.substr(1)}-${name}`);
  tools.replaceInPath(targetPath, '@module.scope.string@', scope.substr(1));
  tools.replaceInPath(targetPath, '@module.class.name@', tools.camelCaseString(`${scope.substr(1)}-${name}`, '-', true));
}




const generateRemote = (args = constants.DEFAULT_CONFIG) => {

  const targetPath = path.join(constants.TARGET_ROOT_REMOTES_PATH, args.fullName);

  tools.logInfo('Generate virtual remote');
  console.log(args);
  tools.logInfo('In target path');
  console.log(targetPath);

  const configOptions = configUtils.global.getConfigOptions();

  let remoteConfigTargetPath;
  if (tools.isDirExists(path.join(process.cwd(), '.config'))) {
    remoteConfigTargetPath = path.join(configOptions.CSDR_REMOTES_CONFIG_PATH , args.fullName);
  } else {
    remoteConfigTargetPath = path.join(configOptions.CSDR_REMOTES_CONFIG_PATH , 'assets', args.fullName);
  }

  return Promise.resolve()
    // INIT and cleanup
    .then(() => {
      tools.logInfo('Cleaning target');
      return tools.rimraf(targetPath + '/**/*');
    })

    // COPY FIRST THE REMOTE SKELETON TO TARGET
    .then(() => {
      // generating default package entries
      const pkg = {
        name: args.fullName,
        repoName: args.repoName,
        npmPkgName: args.npmPkgName,
        paths: {
          root: targetPath
        }
      };

      // ADDING CONFIG ENTRY - specific csdr-remotes as of v15+
      tools.logInfo('Adding CSDR config entry');
      configUtils.register.registerCsdrPackage(
        pkg,
        args.pkgScope, args.pkgName, args.pkgFrontendVersion,
        true,
        args.remoteConfig
      );
    })

    // CLEANING REMOTES CONFIG ENTRY
    .then(() => {
      tools.logInfo('Cleaning remotes-config target entry');
      return tools.rimraf(remoteConfigTargetPath + '/**/*');
    })

    // REPLACING CONTENT FOR VIRTUAL REMOTE CONFIG SKELETON
    .then(() => {
      tools.copy(
        path.join(constants.VIRTUAL_REMOTE_SKELETON_ROOT_PATH, `${args.pkgFrontendVersion}.x`),
        remoteConfigTargetPath
      );

      tools.logInfo('Replace sources content in remotes-config target entry');
      replaceContent(remoteConfigTargetPath, args.pkgName, args.pkgScope, args.fullName);
    })

    // CLEANING REMOTE CURRENT TARGET as this is completetely re-generated by the generateVirtualRemotes() function (same as init)
    .then(() => {
      return tools.rimraf(targetPath + '/**/*');
    })

    // GENERATE THE VIRTUAL REMOTE (as it's dynamically generated, we use here the same fn call as the init)
    .then(() => {
      return initUtils.remotes.generateVirtualRemote(args.fullName, false);
    })

    .then(() => {
      tools.logSuccess();
    })

    .catch((e) => {
      throw e;
    })
}




const generateDefault = (args = constants.DEFAULT_CONFIG) => {

  const targetPath = path.join(constants.TARGET_ROOT_PATH, args.fullName);

  return Promise.resolve()
    // INIT and cleanup
    .then(() => {
      tools.logInfo('Cleaning target');
      return tools.rimraf(targetPath + '/**/*');
    })

    // COPY TO TARGET
    .then(() => {
      tools.logInfo('Copying skeleton to target');
      if (args.pkgFrontendVersion === constants.CONFIG_OPTIONS.pkgFrontendVersion.EUI15) {
        if (args.pkgFrontendParticipant) {
          if (args.pkgFrontendParticipantNgRx) {
            tools.copydir(constants.FRONTEND_SKELETON_EUI15_PARTICIPANT_NGRX_PATH, targetPath, true);
          } else {
            tools.copydir(constants.FRONTEND_SKELETON_EUI15_PARTICIPANT_DEFAULT_PATH, targetPath, true);
          }
        } else {
          tools.copydir(constants.FRONTEND_SKELETON_EUI15_PATH, targetPath, true);
        }
      } else if (args.pkgFrontendVersion === constants.CONFIG_OPTIONS.pkgFrontendVersion.EUI16) {
        if (args.pkgFrontendParticipant) {
          if (args.pkgFrontendParticipantNgRx) {
            tools.copydir(constants.FRONTEND_SKELETON_EUI16_PARTICIPANT_NGRX_PATH, targetPath, true);
          } else {
            tools.copydir(constants.FRONTEND_SKELETON_EUI16_PARTICIPANT_DEFAULT_PATH, targetPath, true);
          }
        } else {
          tools.copydir(constants.FRONTEND_SKELETON_EUI16_PATH, targetPath, true);
        }
      } else if (args.pkgFrontendVersion === constants.CONFIG_OPTIONS.pkgFrontendVersion.EUI17) {
        if (args.pkgFrontendParticipant) {
          if (args.pkgFrontendParticipantNgRx) {
            tools.copydir(constants.FRONTEND_SKELETON_EUI17_PARTICIPANT_NGRX_PATH, targetPath, true);
          } else {
            tools.copydir(constants.FRONTEND_SKELETON_EUI17_PARTICIPANT_DEFAULT_PATH, targetPath, true);
          }
        } else {
          tools.copydir(constants.FRONTEND_SKELETON_EUI17_PATH, targetPath, true);
        }
      } else if (args.pkgFrontendVersion === constants.CONFIG_OPTIONS.pkgFrontendVersion.EUI18) {
        if (args.pkgFrontendParticipant) {
          if (args.pkgFrontendParticipantNgRx) {
            tools.copydir(constants.FRONTEND_SKELETON_EUI18_PARTICIPANT_NGRX_PATH, targetPath, true);
          } else {
            tools.copydir(constants.FRONTEND_SKELETON_EUI18_PARTICIPANT_DEFAULT_PATH, targetPath, true);
          }
        } else {
          tools.copydir(constants.FRONTEND_SKELETON_EUI18_PATH, targetPath, true);
        }
      }

      // REPLACING PLACEHOLDERS
      tools.logInfo('Replace sources content');
      replaceContent(targetPath, args.pkgName, args.pkgScope, args.fullName);

      // REGISTERING PACKAGE in CSDR GLOBAL CONFIG
      tools.logInfo('Registering package');

      // generating default package entries
      const pkg = {
        name: args.fullName,
        repoName: args.repoName,
        npmPkgName: args.npmPkgName,
        paths: {
          root: targetPath
        },
        tsConfigFileName: 'tsconfig.lib.json'
      };

      tools.logInfo('Adding CSDR config entry');
      configUtils.register.registerCsdrPackage(
        pkg, args.pkgScope, args.pkgName, args.pkgFrontendVersion
      );

      configUtils.angular.registerAngularPackage(pkg);
      configUtils.angular.registerModulePaths(pkg);

      replaceExtensions(targetPath);
    })

    .then(() => {
      tools.logSuccess();
    })
    .catch((e) => {
      throw e;
    })
}



module.exports.generate = (args = constants.DEFAULT_CONFIG) => {
  tools.logTitle('Generating frontend package');

  return Promise.resolve()
    .then(() => {
      if (args.pkgFrontendType === constants.CONFIG_OPTIONS.pkgFrontendType.REMOTE) {
        return generateRemote(args);
      } else {
        return generateDefault(args);
      }
    })

    .catch((e) => {
      throw e;
    })
}
