import { isWholeFileChange, WholeFileChange } from '../../file-utils';
import {
  DiffType,
  isJsonChange,
  JsonChange,
} from '../../../utilities/json-diff';
import { TouchedProjectLocator } from '../affected-project-graph-models';

export const getTouchedNpmPackages: TouchedProjectLocator<
  WholeFileChange | JsonChange
> = (
  touchedFiles,
  workspaceJson,
  nxJson,
  packageJson,
  projectGraph
): string[] => {
  const packageJsonChange = touchedFiles.find((f) => f.file === 'package.json');
  if (!packageJsonChange) return [];

  let touched = [];
  const changes = packageJsonChange.getChanges();

  const npmPackages = Object.values(projectGraph.nodes).filter(
    (node) => node.type === 'npm'
  );

  for (const c of changes) {
    if (
      isJsonChange(c) &&
      (c.path[0] === 'dependencies' || c.path[0] === 'devDependencies') &&
      c.path.length === 2
    ) {
      // A package was deleted so mark all workspace projects as touched.
      if (c.type === DiffType.Deleted) {
        touched = Object.keys(workspaceJson.projects);
        break;
      } else {
        touched.push(
          npmPackages.find((pkg) => pkg.data.packageName === c.path[1]).name
        );
      }
    } else if (isWholeFileChange(c)) {
      // Whole file was touched, so all npm packages are touched.
      touched = npmPackages.map((pkg) => pkg.name);
      break;
    }
  }

  return touched;
};
