'use strict';

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

// LOCAL
const tools = require('../../utils/tools');

const innerPackages = require('./packages');
const innerProjects = require('./projects');
const innerRemotes = require('./remotes');
const innerGlobal = require('./global');

// CONFIGS skeletons
const {
  angularConfigDef,
  angularProjectDef,
  angularProjectDefV13,
  angularProjectDefV14,
  angularProjectDefV17,
  angularProjectDefV17esbuild,
  angularProjectDefV19esbuild,
  angularProjectLightDef,
  angularProjectDefFullSkeleton,
  angularProjectDefFullSkeletonV13,
  angularProjectDefFullSkeletonV14,
  angularProjectDefFullSkeletonV17,
  angularProjectDefFullSkeletonV17esbuild,
  angularProjectDefConfiguration,
  angularProjectDefConfigurationHost,
  angularProjectDefConfigurationHostEsbuild,
  angularProjectDefConfigurationLight,
  angularProjectDefConfigurationOptimized,
  angularProjectDefConfigurationOptimizedHost,
  angularProjectDefConfigurationOptimizedHostEsbuild,
  angularProjectDefConfigurationOptimizedLight,
  angularPackageDef,
  angularPackageSubEntryDef,
  angularPackageSubEntryDef15,
  angularPackageDefV13,
  angularPackageDefV14,
  angularPackageDefV15,
  angularPackageDefV15Standalone,
  angularElementProjectDef,
  tsConfigDef,
  tsConfigDefv10,
  tsConfigSpecDef,
  karmaConfDef,
} = require('./config-skeletons');


module.exports.checkConfigFiles = (isReset) => {
  tools.logInfo('Checking config files');

  const rootPath = process.cwd();

  const remoteArg = tools.getArgs().remote;
  const pkgArg = tools.getArgs().pkg;

  let isVirtualRemote = false;

  if (pkgArg) {
    isVirtualRemote = innerRemotes.isVirtualRemote(pkgArg);
  }

  let euiVersion;

  if (remoteArg || isVirtualRemote) {
    let remote;
    if (pkgArg) {
      remote = innerRemotes.getRemote(pkgArg);
    } else {
      remote = innerRemotes.getRemote(remoteArg);
    }
    euiVersion = remote.euiVersion;
  } else {
    euiVersion = innerGlobal.getLocalEuiVersion();
  }

  let euiVersionNumber;

  if (euiVersion) {
    euiVersionNumber = parseInt(euiVersion);
  }

  const angularConfig = path.join(rootPath, 'angular.json');

  let tsConfigDefGen;
  if (euiVersionNumber === 10) {
    tools.logInfo('v10 found, specific injection of tsconfig');
    tsConfigDefGen = tsConfigDefv10;
  } else {
    tools.logInfo('Injecting tsconfig ES2022 based (post v10)');
    tsConfigDefGen = tsConfigDef;
  }

  if (!tools.isFileExists(angularConfig) || isReset) {
    tools.logInfo('Creating angular.json');
    tools.writeJsonFileSync(angularConfig, angularConfigDef);
  }

  tools.logInfo('tsconfig found:');
  console.log(tsConfigDefGen);

  const tsConfigDev = path.join(rootPath, 'tsconfig.json');
  const tsConfigBuild = path.join(rootPath, 'tsconfig.build.json');
  const tsConfigBuildSpec = path.join(rootPath, 'tsconfig.build.spec.json');

  if (!tools.isFileExists(tsConfigDev) || isReset) {
    tools.logInfo('Creating tsconfig.json');
    tools.writeJsonFileSync(tsConfigDev, tsConfigDefGen);
  }
  if (!tools.isFileExists(tsConfigBuild) || isReset) {
    tools.logInfo('Creating tsconfig.build.json');
    tools.writeJsonFileSync(tsConfigBuild, tsConfigDefGen);
  }
  if (!tools.isFileExists(tsConfigBuildSpec) || isReset) {
    tools.logInfo('Creating tsconfig.build.spec.json');
    tools.writeJsonFileSync(tsConfigBuildSpec, tsConfigDefGen);
  }
}

module.exports.checkAngularConfig = () => {
  const angularConfig = path.join(process.cwd(), 'angular.json');

  if (!tools.isFileExists(angularConfig)) {
    tools.logInfo('Creating angular.json');
    tools.writeJsonFileSync(angularConfig, angularConfigDef);
  }
}

module.exports.registerAngularPackage = (pkg, isReset) => {

  const file = path.join(process.cwd(), 'angular.json');
  const jsonFile = require(file);

  var pathBase = 'packages';
  if (pkg.child) {
    pathBase = 'packages/' + pkg.parentPkg + '/packages';
  }

  const packageEuiVersion = innerPackages.getPackageEuiVersion(pkg);
  const packageEuiVersionNumber = parseInt(packageEuiVersion);

  let projectDef = JSON.stringify(angularPackageDef);

  if (packageEuiVersion === '13.x') {
    projectDef = JSON.stringify(angularPackageDefV13);
  }
  if (packageEuiVersion === '14.x') {
    projectDef = JSON.stringify(angularPackageDefV14);
  }
  if (packageEuiVersionNumber >= 15) {
    if (pkg.standalone) {
      projectDef = JSON.stringify(angularPackageDefV15Standalone);
    } else {
      projectDef = JSON.stringify(angularPackageDefV15);
    }
  }

  let srcRoot = '/src', srcRootTesting = '';
  if (!pkg.srcRootDefault) {
    srcRoot = '';
    srcRootTesting = '/testing'
  }

  const replaceModule = tools.replaceAll(projectDef, '@module.name@', pkg.folder || pkg.name);
  const replacePath = tools.replaceAll(replaceModule, '@path@', pathBase);
  const replaceSrcRoot = tools.replaceAll(replacePath, '@srcRoot@', srcRoot);
  const replaceSrcRootTesting = tools.replaceAll(replaceSrcRoot, '@srcRootTesting@', srcRootTesting);
  const replaceTSConfig = tools.replaceAll(replaceSrcRootTesting, '@tsconfig@', pkg.tsConfigFileName);

  jsonFile['projects'][pkg.name] = JSON.parse(replaceTSConfig);

  tools.writeJsonFileSync(file, jsonFile);
}


module.exports.registerAngularPackageSubEntry = (subEntryName, subEntryPath, pkg) => {
  const file = path.join(process.cwd(), 'angular.json');
  const jsonFile = require(file);

  const packageEuiVersion = innerPackages.getPackageEuiVersion(pkg);
  const packageEuiVersionNumber = parseInt(packageEuiVersion);

  let projectDef = JSON.stringify(angularPackageSubEntryDef);

  if (packageEuiVersionNumber >= 15) {
    projectDef = JSON.stringify(angularPackageSubEntryDef15);
    projectDef = projectDef.replace('"main":"packages/eui/packages/components/@subEntry.path@/test.ts",', '');
  }
  projectDef = tools.replaceAll(projectDef, '@subEntry.path@', subEntryName)
  projectDef = tools.replaceAll(projectDef, '@subEntry.package.name@', 'ng-package.json');
  projectDef = tools.replaceAll(projectDef, '@tsconfig@', pkg.tsConfigFileName);

  if (packageEuiVersionNumber >= 15) {
    // if tsconfig is missing add it
    const tsConfigSpecPath = path.join(process.cwd(), JSON.parse(projectDef).architect.test.options.tsConfig);
    // check if tsconfig exists otherwise created it
    if (!tools.isFileExists(tsConfigSpecPath)) {
      // determine tsconfig path
      const tsConfigFolder = JSON.parse(projectDef).architect.build.options.tsConfig.replace(/\/tsconfig.*/g, '');
      const projectFolder = JSON.parse(projectDef).architect.build.options.project.replace('/ng-package.json', '');
      const parent = projectFolder.replace(tsConfigFolder, '').split('/').length - 1;
      // calculate the parent tsconfig path
      tsConfigSpecDef.extends = '../'.repeat(parent) + 'tsconfig.json';

      // check if parent tsconfig.json is missing
      if(!tools.isFileExists(path.join(process.cwd(), projectFolder,  tsConfigSpecDef.extends))) {
        tools.logError('The tsconfig.json file is missing in the parent folder of the sub entry: ' + subEntryName);
        return;
      }

      tools.writeJsonFileSync(tsConfigSpecPath, tsConfigSpecDef);
    }

    // if karma.conf.js is missing add it
    const karmaConfPath = path.join(process.cwd(), JSON.parse(projectDef).architect.test.options.karmaConfig);
    if(!tools.isFileExists(karmaConfPath)) {
      tools.writeFileContent(karmaConfPath, karmaConfDef)
    }
  }

  jsonFile['projects'][subEntryName] = JSON.parse(projectDef);

  // console.log(jsonFile['projects'][subEntryName]);

  tools.writeJsonFileSync(file, jsonFile);
}





module.exports.registerAngularProjectDef = (project, build = false, element = false) => {
  tools.logInfo('Registering angular project definition...');

  // checking if root angular.json exists, create if not
  const file = path.join(process.cwd(), 'angular.json');

  // getting the eUI version of the project and setting path
  let euiVersion;
  let angularRootPath;

  if (element) {
    euiVersion = innerPackages.getPackageEuiVersion(project);
    angularRootPath = project.paths.root;
  } else {
    euiVersion = innerProjects.getProjectEuiVersion(project);

    if (!euiVersion) {
      if (project.build && project.build.euiVersion) {
        euiVersion = project.build.euiVersion;
      }
    }

    angularRootPath = project.paths.angularPath;
  }


  tools.logInfo(`Registering angular project for eUI version : ${euiVersion}`);

  const packageEuiVersionNumber = parseInt(euiVersion);

  if (!tools.isFileExists(file)) {
    tools.writeJsonFileSync(file, angularConfigDef);
  }

  // injecting angular project definition
  let angularConfigFile;

  if (tools.isFileExists(path.join(angularRootPath, 'angular-config.json'))) {
    tools.logInfo(`Registering project angular config...`);
    const angularConfigFilePath = path.join(angularRootPath, 'angular-config.json');
    delete require.cache[angularConfigFilePath];
    angularConfigFile = require(angularConfigFilePath);
  }

  if (angularConfigFile) {
    const jsonFile = require(file);

    // if the local project contains the full config entry, we take the existing
    if (angularConfigFile.config) {
      tools.logInfo('Full angular config detected...injecting');
      jsonFile['projects'][project.name] = angularConfigFile.config;

      // otherwise we take only the parts that have been declared and default template is used
    } else {
      tools.logInfo('Processing angular config...');
      let projectDef;
      if (project.csdrFullSkeleton) {
        if (euiVersion === '13.x') {
          projectDef = JSON.stringify(angularProjectDefFullSkeletonV13);
          tools.logInfo(`----using angularProjectDefFullSkeletonV13`);
        } else if (euiVersion === '14.x' || euiVersion === '15.x' || euiVersion === '16.x') {
          projectDef = JSON.stringify(angularProjectDefFullSkeletonV14);
          tools.logInfo(`----using angularProjectDefFullSkeletonV14`);
        } else if (packageEuiVersionNumber >= 17) {
          if (project.build.esbuild) {
            projectDef = JSON.stringify(angularProjectDefFullSkeletonV17esbuild);
            tools.logInfo(`----using angularProjectDefFullSkeletonV17esbuild`);
          } else {
            projectDef = JSON.stringify(angularProjectDefFullSkeletonV17);
            tools.logInfo(`----using angularProjectDefFullSkeletonV17`);
          }
        } else {
          projectDef = JSON.stringify(angularProjectDefFullSkeleton);
          tools.logInfo(`----using angularProjectDefFullSkeleton`);
        }

      } else {
        if (euiVersion === '13.x') {
          projectDef = JSON.stringify(angularProjectDefV13);
          tools.logInfo(`----using angularProjectDefV13`);
        } else if (euiVersion === '14.x' || euiVersion === '15.x' || euiVersion === '16.x') {
          projectDef = JSON.stringify(angularProjectDefV14);
          tools.logInfo(`----using angularProjectDefV14`);
        } else if (euiVersion === '17.x') {
          projectDef = JSON.stringify(angularProjectDefV17);
          tools.logInfo(`----using angularProjectDefV17`);
        } else if (packageEuiVersionNumber === 18 && packageEuiVersionNumber < 19) {
          projectDef = JSON.stringify(angularProjectDefV17esbuild);
          tools.logInfo(`----using angularProjectDefV17esbuild`);
        } else if (packageEuiVersionNumber >= 19) {
          projectDef = JSON.stringify(angularProjectDefV19esbuild);
          tools.logInfo(`----using angularProjectDefV19esbuild`);
        } else {
          if (project.build && project.build.csdrFileReplacement === true) {
            projectDef = JSON.stringify(angularProjectLightDef);
            tools.logInfo(`----using angularProjectLightDef`);
          } else {
            projectDef = JSON.stringify(angularProjectDef);
            tools.logInfo(`----using angularProjectDef`);
          }
        }
      }
      let replaceProject = tools.replaceAll(projectDef, '@project.name@', project.name);
      if (project.virtual && project.host) {
        replaceProject = tools.replaceAll(replaceProject, 'apps/', 'hosts/');
      }
      replaceProject = JSON.parse(replaceProject);

      jsonFile['projects'][project.name] = replaceProject;

      // replacing overridden config if any
      tools.logInfo('Processing assets injection...');
      if (angularConfigFile.build.assets.length > 0) {
        if (build && angularConfigFile.build.assetsBuild && angularConfigFile.build.assetsBuild.length > 0) {
          jsonFile['projects'][project.name].architect.build.options.assets = angularConfigFile.build.assetsBuild;
        } else {
          jsonFile['projects'][project.name].architect.build.options.assets = angularConfigFile.build.assets;
        }
      }

      tools.logInfo('Processing styles injection...');
      if (angularConfigFile.build.styles.length > 0) {
        if (build && angularConfigFile.build.stylesBuild && angularConfigFile.build.stylesBuild.length > 0) {
          jsonFile['projects'][project.name].architect.build.options.styles = angularConfigFile.build.stylesBuild;
        } else {
          jsonFile['projects'][project.name].architect.build.options.styles = angularConfigFile.build.styles;
        }
      }

      tools.logInfo('Processing scripts injection...');
      if (angularConfigFile.build.scripts && angularConfigFile.build.scripts.length > 0) {
        jsonFile['projects'][project.name].architect.build.options.scripts = angularConfigFile.build.scripts;
      }

      tools.logInfo('Processing base href injection...');
      if (angularConfigFile.build.baseHref) {
        jsonFile['projects'][project.name].architect.build.options.baseHref = angularConfigFile.build.baseHref;
      }

      // replacing custom configurations if provided
      if (angularConfigFile.configurations && angularConfigFile.configurations.length > 0) {
        tools.logInfo('Processing configurations injection');

        let configurationDef, configurationDefOptimized;
        if (project.build && project.build.csdrFileReplacement) {
          if (packageEuiVersionNumber >= 18) {
            tools.logInfo('Injecting angular configuration for 18+ - file replacement is handled by CSDR');
            configurationDef = JSON.stringify(angularProjectDefConfigurationHostEsbuild);
            configurationDefOptimized = JSON.stringify(angularProjectDefConfigurationOptimizedHostEsbuild);
          } else {
            tools.logInfo('Injecting light angular configuration - file replacement is handled by CSDR');
            configurationDef = JSON.stringify(angularProjectDefConfigurationLight);
            configurationDefOptimized = JSON.stringify(angularProjectDefConfigurationOptimizedLight);
          }
        } else {
          tools.logInfo('Injecting angular configuration file replacement');
          if (project.host) {
            if (packageEuiVersionNumber >= 18) {
              configurationDef = JSON.stringify(angularProjectDefConfigurationHostEsbuild);
              configurationDefOptimized = JSON.stringify(angularProjectDefConfigurationOptimizedHostEsbuild);
            } else {
              configurationDef = JSON.stringify(angularProjectDefConfigurationHost);
              configurationDefOptimized = JSON.stringify(angularProjectDefConfigurationOptimizedHost);
            }
          } else {
            configurationDef = JSON.stringify(angularProjectDefConfiguration);
            configurationDefOptimized = JSON.stringify(angularProjectDefConfigurationOptimized);
          }
        }

        angularConfigFile.configurations.forEach((conf) => {
          const confKey = Object.keys(conf)[0];
          const confValue = conf[confKey];

          tools.logInfo(`Injecting : ${confKey} - ${confValue}`);

          let replaceConfiguration = '';
          if (confKey.indexOf('local') > -1) {
            tools.logInfo('Local injection (non-optimized)');
            try {
              if (confKey.indexOf('cdn') > -1) {
                let localIndexFilePath = 'hosts/' + project.name + '/src/index-local';
                if (confKey.indexOf('dev') > -1) {
                  localIndexFilePath += '-dev';
                } else if (confKey.indexOf('tst') > -1) {
                  localIndexFilePath += '-tst';
                }
                localIndexFilePath += '.html';
                const configurationDefObject = JSON.parse(configurationDef);
                configurationDefObject.index = localIndexFilePath;
                configurationDef = JSON.stringify(configurationDefObject);
              }
            } catch (error) {
              tools.logError('Failed to replace local index.html file.');
            }
            replaceConfiguration = tools.replaceAll(configurationDef, '@config.filename@', confValue);
          } else {
            tools.logInfo('Env injection - optimized');
            replaceConfiguration = tools.replaceAll(configurationDefOptimized, '@config.filename@', confValue);
          }

          replaceConfiguration = tools.replaceAll(replaceConfiguration, '@project.name@', project.name);
          replaceConfiguration = tools.replaceAll(replaceConfiguration, '@config.key@', confKey);
          replaceConfiguration = JSON.parse(replaceConfiguration);

          // writing build configuration entry
          jsonFile['projects'][project.name].architect.build.configurations[confKey] = replaceConfiguration;

          // writing serve configuration entry
          let serveConf;
          if (packageEuiVersionNumber >= 19) {
            serveConf = { buildTarget: project.name + ':build:' + confKey };
          } else {
            serveConf = { browserTarget: project.name + ':build:' + confKey };
          }
          // add proxy configuration
          if (confKey.startsWith('cdn-') && confKey.endsWith('-local')) {
            serveConf ['proxyConfig'] = 'hosts/' + project.name + '/proxy-' + confKey + '-openid.conf.js';
          }
          jsonFile['projects'][project.name].architect.serve.configurations[confKey] = serveConf;
        })
      }

      // checking pwa additional injection
      if (project.build && project.build.pwa) {
        jsonFile['projects'][project.name].architect.build.options.serviceWorker = true;
        if (packageEuiVersionNumber >= 18) {
          jsonFile['projects'][project.name].architect.build.options.serviceWorker = `${project.folder}/ngsw-config.json`;
        } else {
          jsonFile['projects'][project.name].architect.build.options.ngswConfigPath = `${project.folder}/ngsw-config.json`;
        }
        jsonFile['projects'][project.name].architect.build.options.assets.push(`apps/${project.name}/src/manifest.webmanifest`);
      }
    }

    tools.writeJsonFileSync(file, jsonFile);
  }
}


module.exports.registerAngularElementModule = (pkg) => {

  const file = path.join(process.cwd(), 'angular.json');

  const jsonFile = require(file);
  jsonFile['projects'][pkg.name] = JSON.parse(tools.replaceAll(JSON.stringify(angularElementProjectDef), '@module.name@', pkg.name));

  tools.writeJsonFileSync(file, jsonFile);
}




module.exports.registerModulePaths = (pkg, isReset) => {
  tools.logInfo(`Registering tsconfig paths for package : ${pkg.name}`);

  const fileDev = path.join(process.cwd(), 'tsconfig.json');
  const fileBuild = path.join(process.cwd(), 'tsconfig.build.json');
  const fileBuildSpec = path.join(process.cwd(), 'tsconfig.build.spec.json');
  let defFile;
  if (tools.isDirExists(path.join(process.cwd(), '.config'))) {
    defFile = path.join(process.cwd(), '.config', '.euirc-apps.json');
  } else {
    defFile = path.join(process.cwd(), '.csdr', '.euirc-csdr-apps.json');
  }

  if ((!tools.isFileExists(fileBuild) || isReset) && !tools.isFileExists(defFile)) {
    tools.copy(fileDev, fileBuild);
  }
  if ((!tools.isFileExists(fileBuildSpec) || isReset) && !tools.isFileExists(defFile)) {
    tools.copy(fileDev, fileBuildSpec);
  }

  let jsonFileDev, jsonFileBuild, jsonFileBuildSpec;
  if (!tools.isFileExists(fileDev)) {
    jsonFileDev = tsConfigDef;
  } else {
    jsonFileDev = require(fileDev);
  }

  if (!tools.isFileExists(fileBuild)) {
    jsonFileBuild = tsConfigDef;
  } else {
    jsonFileBuild = require(fileBuild);
  }

  if (!tools.isFileExists(fileBuildSpec)) {
    jsonFileBuildSpec = tsConfigDef;
  } else {
    jsonFileBuildSpec = require(fileBuildSpec);
  }

  var pathBase = './packages';
  if (pkg.child) {
    pathBase = './packages/' + pkg.parentPkg + '/packages';
  }

  if (!jsonFileDev['compilerOptions']['paths']) {
    jsonFileDev['compilerOptions']['paths'] = {};
  }
  if (!jsonFileBuild['compilerOptions']['paths']) {
    jsonFileBuild['compilerOptions']['paths'] = {};
  }
  if (!jsonFileBuildSpec['compilerOptions']['paths']) {
    jsonFileBuildSpec['compilerOptions']['paths'] = {};
  }

  if (!pkg.paths || tools.isDirExists(pkg.paths.src)) {
    if (pkg.paths) {
      tools.logInfo(`${pkg.paths.src} exists => pointing to /src folder`);
    }
    jsonFileDev['compilerOptions']['paths'][`${pkg.npmPkgScope}/${pkg.npmPkgName}`] = [`${pathBase}/${pkg.folder || pkg.name}/src`];
    jsonFileDev['compilerOptions']['paths'][`${pkg.npmPkgScope}/${pkg.npmPkgName}/*`] = [`${pathBase}/${pkg.folder || pkg.name}/src`];
    jsonFileBuild['compilerOptions']['paths'][`${pkg.npmPkgScope}/${pkg.npmPkgName}`] = [`${pathBase}/${pkg.folder || pkg.name}/dist`];
    jsonFileBuild['compilerOptions']['paths'][`${pkg.npmPkgScope}/${pkg.npmPkgName}/*`] = [`${pathBase}/${pkg.folder || pkg.name}/dist`];
    jsonFileBuildSpec['compilerOptions']['paths'][`${pkg.npmPkgScope}/${pkg.npmPkgName}`] = [`${pathBase}/${pkg.folder || pkg.name}/dist`];
    jsonFileBuildSpec['compilerOptions']['paths'][`${pkg.npmPkgScope}/${pkg.npmPkgName}/*`] = [`${pathBase}/${pkg.folder || pkg.name}/dist`];

  } else {
    tools.logInfo(`${pkg.paths.src} does not exist => pointing to root folder`);
    jsonFileDev['compilerOptions']['paths'][`${pkg.npmPkgScope}/${pkg.npmPkgName}`] = [`${pathBase}/${pkg.folder || pkg.name}`];
    jsonFileDev['compilerOptions']['paths'][`${pkg.npmPkgScope}/${pkg.npmPkgName}/*`] = [`${pathBase}/${pkg.folder || pkg.name}/*`];
    jsonFileBuild['compilerOptions']['paths'][`${pkg.npmPkgScope}/${pkg.npmPkgName}`] = [`${pathBase}/${pkg.folder || pkg.name}/dist`];
    jsonFileBuild['compilerOptions']['paths'][`${pkg.npmPkgScope}/${pkg.npmPkgName}/*`] = [`${pathBase}/${pkg.folder || pkg.name}/dist/*`];
    jsonFileBuildSpec['compilerOptions']['paths'][`${pkg.npmPkgScope}/${pkg.npmPkgName}`] = [`${pathBase}/${pkg.folder || pkg.name}`];
    jsonFileBuildSpec['compilerOptions']['paths'][`${pkg.npmPkgScope}/${pkg.npmPkgName}/*`] = [`${pathBase}/${pkg.folder || pkg.name}/*`];
  }


  tools.writeJsonFileSync(fileDev, jsonFileDev);
  tools.writeJsonFileSync(fileBuild, jsonFileBuild);
  tools.writeJsonFileSync(fileBuildSpec, jsonFileBuildSpec);
}




module.exports.registerProjectExtraPaths = (project, isReset) => {
  const fileDev = path.join(process.cwd(), 'tsconfig.json');
  const fileBuild = path.join(process.cwd(), 'tsconfig.build.json');

  const extraPathsFile = path.join(process.cwd(), project.folder, 'tsconfig-extra-paths.json');

  if (!tools.isFileExists(extraPathsFile)) {
    return;
  }

  if ((!tools.isFileExists(fileBuild) || isReset) && !tools.isFileExists(defFile)) {
    tools.copy(fileDev, fileBuild);
  }

  const jsonFileDev = require(fileDev);
  const jsonFileBuild = require(fileBuild);
  const jsonExtraPathsFile = require(extraPathsFile);

  if (!jsonFileDev['compilerOptions']['paths']) {
    jsonFileDev['compilerOptions']['paths'] = {};
  }
  if (!jsonFileBuild['compilerOptions']['paths']) {
    jsonFileBuild['compilerOptions']['paths'] = {};
  }

  jsonFileDev['compilerOptions']['paths'] = { ...jsonFileDev['compilerOptions']['paths'], ...jsonExtraPathsFile };
  jsonFileBuild['compilerOptions']['paths'] = { ...jsonFileBuild['compilerOptions']['paths'], ...jsonExtraPathsFile };

  tools.writeJsonFileSync(fileDev, jsonFileDev);
  tools.writeJsonFileSync(fileBuild, jsonFileBuild);
}
