import '../../../../globals.js';
// Copyright 2022-2024, University of Colorado Boulder

/**
 * Runs tasks for pre-commit, including lint and qunit testing.
 *
 * Should only be run when developing in main, because when dependency shas are checked out for one sim,
 * they will likely be inconsistent for other repos which would cause failures for cross-repo processes like type checking.
 * This means when running maintenance release steps, you may need to run git commands with --no-verify.
 *
 * Timing data is streamed through phetTimingLog, please see that file for how to see the results live and/or afterwards.
 *
 * USAGE:
 * cd ${repo}
 * sage run ../chipper/js/scripts/pre-commit.js
 *
 * OPTIONS:
 * --console: outputs information to the console for debugging
 * --allTasks: forces all tasks to run, even if they are disabled in the local preferences
 * --changed: run on all repos with working copy changes
 * --all: run on all repos
 * --absolute: output paths that WebStorm External Tools can parse and hyperlink
 *
 * TASKS:
 * --lint: runs eslint on the repo
 * --report-media: checks for missing or unused media files
 * --type-check: runs type-check.js
 * --unit-test: runs qunit tests
 * --phet-io-api: compares the PhET-iO API with the previous version
 * --*: apply to all tasks, for example "--*=false --lint=true" will turn off all tasks except lint, ignoring the buildLocal defaults.
 *
 * DEFAULTS in build-local.json
 * By default all tasks will be run for every repo if that repo supports the task. Specify opt-out behavior for this
 * grunt task AND the actual pre-commit hooks via the 'hookPreCommit` key in build-local.json.
 * Keys are the name of the task (see above), and values are boolean, true means test that task. Use '*' to apply to
 * all tasks. For example:
 * MK: opts out of phet-io api checking:
 * "hookPreCommit": {
 *   "phet-io-api": false,
 * }
 * SR: runs them manually, and turns them off for the git hooks:
 * "hookPreCommit": {
 *   "*": false, // This key takes precedent, so all other keys here would be ignored.
 * },
 * If someone didn't want linting or type checking:
 * "hookPreCommit": {
 *   "lint": false,
 *   "type-check": false,
 * },
 *
 * See also phet-info/git-template-dir/hooks/pre-commit for how this is used in precommit hooks.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */

import getActiveRepos from '../../../../perennial-alias/js/common/getActiveRepos.js';
import getReposWithWorkingCopyChanges from '../../../../perennial-alias/js/common/getReposWithWorkingCopyChanges.js';
import getOption from '../../../../perennial-alias/js/grunt/tasks/util/getOption.js';
import getRepo from '../../../../perennial-alias/js/grunt/tasks/util/getRepo.js';
import { preCommitMain } from '../../common/pre-commit/preCommitMain.js';
import preCommitOnRepos from '../../common/pre-commit/preCommitOnRepos.js';

// These repos do not require precommit hooks to be run
const optOutRepos = [

  // The files here are predominantly autogenerated and unlikely to be broken. Also, every repo depends on babel
  // so running pre-commit hooks here takes a significant amount of time
  'babel'
];

const repo = getRepo();

const outputToConsole = getOption( 'console' ); // Console logging via --console

( async () => {

  // Re-spawn the same process on repos with working copy changes
  if ( getOption( 'changed' ) ) {
    const changedRepos = await getReposWithWorkingCopyChanges();
    const success = await preCommitOnRepos( changedRepos, outputToConsole );
    process.exit( success ? 0 : 1 );
    return;
  }

  // Re-spawn the same process on all repos
  if ( getOption( 'all' ) ) {
    const success = await preCommitOnRepos( getActiveRepos(), outputToConsole );
    process.exit( success ? 0 : 1 );
    return;
  }

  if ( optOutRepos.includes( repo ) ) {
    console.log( `Skipping precommit hooks for the repo: ${repo}` );
    process.exit( 0 );
  }

  await preCommitMain( repo, outputToConsole );
} )();