/**
 * @license
 * Copyright (C) 2020 The Android Open Source Project
 *
 * 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 * as path from "path";
import * as fs from "fs";
import {isSharedFileLicenseInfo, LicenseInfo, PackageInfo} from "./package-license-info";
import {LicenseName, PackageName, FilePath, PackageVersion} from "./base-types";
import { InstalledPackage, InsalledPackagesBuilder } from "./installed-node-modules-map";
import {SharedLicensesProvider} from "./shared-licenses-provider";
import {fail} from "./utils";

interface FilteredFiles {
  installedPackage: InstalledPackage;
  /** Path relative to installedPackage */
  includedFiles: FilePath[];
  /** Path relative to installedPackage */
  excludedFiles: FilePath[];
}
interface PackageLicensedFiles {
  packageInfo: PackageInfo;
  filteredFiles: FilteredFiles;
}

enum LicensedFilesDisplayInfoType {
  AllFiles = "AllFiles",
  OnlySpecificFiles = "OnlySpecificFiles",
  AllFilesExceptSpecific = "AllFilesExceptSpecific",
}

interface AllFiles {
  kind: LicensedFilesDisplayInfoType.AllFiles;
}

interface AllFilesExceptSpecificFiles {
  kind: LicensedFilesDisplayInfoType.AllFilesExceptSpecific;
  /** Path relative to installedPackage */
  files: FilePath[]
}

interface OnlySpecificFiles {
  kind: LicensedFilesDisplayInfoType.OnlySpecificFiles;
  /** Path relative to installedPackage */
  files: FilePath[];
}

export type FilteredFilesDisplayInfo = AllFiles | AllFilesExceptSpecificFiles | OnlySpecificFiles;

export interface LicenseMapPackageInfo {
  name: PackageName;
  version: PackageVersion;
  licensedFiles: FilteredFilesDisplayInfo;
}

export interface LicenseMapItem {
  licenseName: LicenseName,
  licenseText: string;
  packages: LicenseMapPackageInfo[];
}

export type LicensesMap = { [licenseName: string]:  LicenseMapItem }

/** LicenseMapGenerator calculates license map for nodeModulesFiles.
 */
export class LicenseMapGenerator {
  /**
   *  packages - information about licenses for packages
   *  sharedLicensesProvider - returns text for shared licenses by name
   */
  public constructor(private readonly packages: ReadonlyArray<PackageInfo>, private readonly sharedLicensesProvider: SharedLicensesProvider) {
  }

  /** generateMap calculates LicenseMap for nodeModulesFiles
   * Each (key, value) pair in this map has the following information:
   * The key is a license name.
   * The value contains information about packages and files for which this license
   * is applied.
   *
   * The method tries to provide information in a compact way:
   * 1) If all files in the package have the same license, then it stores a name of the package
   *    without list of files
   * 2) If different files in the package has different licenses, then the method calculates
   *    which list is shorter - list of included files or list of excluded files.
   */
  public generateMap(nodeModulesFiles: ReadonlyArray<string>): LicensesMap {
    const installedPackages = this.getInstalledPackages(nodeModulesFiles);
    // Static packages that are not inside `node_modules` directories.
    // gr-page.ts was derived from page.js, so we reproduce the original LICENSE.
    installedPackages.push({name: 'polygerrit-gr-page', version: 'current', rootPath: 'polygerrit-ui/app/elements/core/gr-router/', files: ['gr-page.ts']});
    const licensedFilesGroupedByLicense = this.getLicensedFilesGroupedByLicense(installedPackages);

    const result: LicensesMap = {};
    licensedFilesGroupedByLicense.forEach((packageLicensedFiles, licenseName) => {
      result[licenseName] = this.getLicenseMapItem(licenseName, packageLicensedFiles);
    });
    return result;
  }

  private getLicenseMapItem(licenseName: string, packagesLicensedFiles: PackageLicensedFiles[]): LicenseMapItem {
    const packages: LicenseMapPackageInfo[] = [];
    let licenseText: string = "";
    packagesLicensedFiles.forEach((packageLicensedFiles) => {
      const packageLicenseText = this.getLicenseText(packageLicensedFiles);
      if (licenseText.length !== 0 && packageLicenseText !== licenseText) {
        fail(`There are different license texts for license '${licenseName}'.\n` +
            "Probably, you have multiple version of the same package.\n" +
            "In this case you must define different license name for each version"
        );
      }
      licenseText = packageLicenseText;
      packages.push({
        name: packageLicensedFiles.packageInfo.name,
        version: packageLicensedFiles.filteredFiles.installedPackage.version,
        licensedFiles: this.getFilteredFilesDisplayInfo(packageLicensedFiles.filteredFiles)
      });
    });
    return {
      licenseName,
      licenseText,
      packages
    };
  }

  /** getFilteredFilesDisplayInfo calculates the best method to display information about
   * filteredFiles in filteredFiles.installedPackage
   * In the current implementation - the best method is a method with a shorter list of files
   *
   * Each {@link PackageInfo} has a filter for files (by default all files
   * are included). Applying filter to files from an installedPackage returns 2 lists of files:
   * includedFiles (i.e. files with {@link PackageInfo.license} license) and excludedFiles
   * (i.e. files which have different license(s)).
   *
   * A text representaion of license-map must have full information about per-file licenses if
   * needed, but we want to produce files lists there as short as possible
   */
  private getFilteredFilesDisplayInfo(filteredFiles: FilteredFiles): FilteredFilesDisplayInfo {
    if (filteredFiles.includedFiles.length > 0 && filteredFiles.excludedFiles.length === 0) {
      /** All files from package are included (i.e. all files have the same license).
       * It is enough to print only installedPackage name.
       * */
      return {
        kind: LicensedFilesDisplayInfoType.AllFiles
      }
    } else if (filteredFiles.includedFiles.length <= filteredFiles.excludedFiles.length) {
      /** After applying filter, the number of files with filteredFiles.license is less than
       * the number of excluded files.
       * It is more convenient to print information about license in the format:
       * GIT license - fontPackage (only files A,B,C)*/
      return {
        kind: LicensedFilesDisplayInfoType.OnlySpecificFiles,
        files: filteredFiles.includedFiles
      };
    } else {
      /** Only few files from filteredFiles.installedPackage has filteredFiles.license.
       * It is more convenient to print information about license in the format:
       * Apache license - fontPackage (except files A,B,C)
       */
      return {
        kind: LicensedFilesDisplayInfoType.AllFilesExceptSpecific,
        files: filteredFiles.excludedFiles
      }
    }
  }

  private getLicensedFilesGroupedByLicense(installedPackages: InstalledPackage[]): Map<LicenseName, PackageLicensedFiles[]> {
    const result: Map<LicenseName, PackageLicensedFiles[]> = new Map();
    installedPackages.forEach(installedPackage => {
      // It is possible that different files in package have different licenses.
      // See the getPackageInfosForInstalledPackage method for details.
      const packageInfos = this.findPackageInfosForInstalledPackage(installedPackage);
      if(packageInfos.length === 0) {
        fail(`License for package '${installedPackage.name}-${installedPackage.version}' was not found`);
      }

      const allPackageLicensedFiles: Set<string> = new Set();
      packageInfos.forEach(packInfo => {
          const licensedFiles = this.filterFilesByPackageInfo(installedPackage, packInfo);
          if(licensedFiles.includedFiles.length === 0) {
            return;
          }
          const license = packInfo.license;
          if (!license.type.allowed) {
            fail(`Polygerrit bundle use files with invalid licence ${license.name} from` +
                ` the package ${installedPackage.name}`);
          }
          if(!result.has(license.name)) {
            result.set(license.name, []);
          }
          result.get(license.name)!.push({
            packageInfo: packInfo,
            filteredFiles: licensedFiles
          });
          licensedFiles.includedFiles.forEach((fileName) => {
            if(allPackageLicensedFiles.has(fileName)) {
              fail(`File '${fileName}' from '${installedPackage.name}' has multiple licenses.`)
            }
            allPackageLicensedFiles.add(fileName);
          });
        });
      if(allPackageLicensedFiles.size !== installedPackage.files.length) {
        fail(`Some files from '${installedPackage.name}' doesn't have a license, but they are used during build`);
      }
      });
    return result;
  }

  /** getInstalledPackages Collects information about all installed packages */
  private getInstalledPackages(nodeModulesFiles: ReadonlyArray<string>): InstalledPackage[] {
    const fullNonPackageNames: string[] = [];
    for (const p of this.packages) {
      if (p.nonPackages) {
        fullNonPackageNames.push(...p.nonPackages.map(name => `${p.name}/${name}`));
      }
    }
    const builder = new InsalledPackagesBuilder(new Set(fullNonPackageNames));
    // Register all package.json files - such files exists in the root folder of each module
    let packageJsonFiles = nodeModulesFiles.filter(f => path.basename(f) === "package.json");
    // The `safevalue` node module has an unusual setup: It also includes (meaningless) package.json
    // file in the dist directory that the license map generator cannot quite process. So let's
    // ignore them here.
    if (packageJsonFiles.some(path => path.includes('safevalues/package.json'))) {
      packageJsonFiles = packageJsonFiles.filter(path => !path.includes('safevalues/') || path.includes('safevalues/package.json'));
    }
    packageJsonFiles.forEach(packageJsonFile => builder.addPackageJson(packageJsonFile));
    // Iterate through all files. builder adds each file to appropriate package
    nodeModulesFiles.forEach(f => builder.addFile(f));
    return builder.build();
  }

  /**
   * findPackageInfosForInstalledPackage finds all possible licenses for the installedPackage.
   * It is possible, that different files in package have different licenses.
   * For example, @polymer/font-roboto-local package has files with 2 different licenses
   * - .js files - Polymer license (i.e. BSD),
   * - font files - Apache 2.0 license
   * In this case, the package is defined several times with different filesFilter
   */
  private findPackageInfosForInstalledPackage(installedPackage: InstalledPackage): PackageInfo[] {
    return this.packages.filter(packInfo => {
      if(packInfo.name !== installedPackage.name) {
        return false;
      }
      return !packInfo.versions || packInfo.versions.indexOf(installedPackage.version) >= 0;
    });
  }

  /** Returns list of files which have license defined in packageInfo */
  private filterFilesByPackageInfo(installedPackage: InstalledPackage, packageInfo: PackageInfo): FilteredFiles {
    const filter = packageInfo.filesFilter;
    if(!filter) {
      return {
        installedPackage,
        includedFiles: installedPackage.files,
        excludedFiles: [],
      }
    }
    return installedPackage.files.reduce((result: FilteredFiles, f) => {
      if(filter(f)) {
        result.includedFiles.push(f);
      } else {
        result.excludedFiles.push(f);
      }
      return result;
    }, {
      installedPackage,
      includedFiles: [],
      excludedFiles: []
    });
  }

  private getLicenseText(packageInfo: PackageLicensedFiles) {
    if(isSharedFileLicenseInfo(packageInfo.packageInfo.license)) {
      return this.sharedLicensesProvider.getText(packageInfo.packageInfo.license.sharedLicenseFile);
    } else {
      const filePath = path.join(packageInfo.filteredFiles.installedPackage.rootPath,
          packageInfo.packageInfo.license.packageLicenseFile)
      return fs.readFileSync(filePath, {encoding: 'utf-8'});
    }
  }
}

