/**
 * @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
    nodeModulesFiles.filter(f => path.basename(f) === "package.json")
      .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'});
    }
  }
}

