import initPrompt from 'prompt-sync';
import clear from 'clear';

// Import shared helpers
import print from './helpers/print';
import exec from './helpers/exec';
import getMajorNodeVersionInDockerfile from './helpers/getMajorNodeVersionInDockerfile';
import getCurrentEvenLTSNodeVersion from './helpers/getCurrentEvenLTSNodeVersion';

/*----------------------------------------*/
/* ------------- Init Prompt ------------ */
/*----------------------------------------*/

const promptSync = initPrompt();

/**
 * Ask the user a question
 * @param title title of the question
 * @param notRequired true if question is not required
 * @returns response
 */
const prompt = (title: string, notRequired?: boolean): string => {
  const val = promptSync(title);
  if (val === null || (!notRequired && !val)) {
    process.exit(0);
  }
  return val;
};

// Save the prompt for use later
print.savePrompt(prompt);

/*----------------------------------------*/
/* ---------------- Main ---------------- */
/*----------------------------------------*/

/**
 * Synchronizes the environment variables between the user's machine
 * and the Dockerfile of the current project
 * @author Gabe Abrams
 */
(async () => {
  // Validate node version
  const currentEvenMajorLTSVersion = await getCurrentEvenLTSNodeVersion();
  const nodeMajorVersion = await getMajorNodeVersionInDockerfile();
  if (!currentEvenMajorLTSVersion) {
    print.title('Node Version Error');
    console.log('');
    console.error('Unable to find the latest even LTS version of Node.js.');
    console.error('Please check your internet connection and try again.');
    process.exit(1);
  }
  if (!nodeMajorVersion) {
    print.title('Node Version Not Found');
    console.log('');
    console.error('Unable to find the version of Node.js in the Dockerfile.');
    console.error('Please check the Dockerfile and try again.');
    process.exit(1);
  }
  const nodeUpToDate = nodeMajorVersion === currentEvenMajorLTSVersion;
  if (!nodeUpToDate) {
    print.title('!!! Node OUT OF DATE !!!');
    console.log('');
    console.error(`The version of Node.js in the Dockerfile is ${nodeMajorVersion}.`);
    console.error(`The latest even LTS version of Node.js is ${currentEvenMajorLTSVersion}.`);
    console.error('Please update the Dockerfile soon:');
    console.error(`FROM node:${currentEvenMajorLTSVersion}-alpine`);
    console.error('');
    print.enterToContinue();
    clear();
  }

  // Synchronize environment
  console.log('Synchronizing environment...');
  const usingNodeVersion = exec('node --version');
  const usingNodeMajorVersionString = usingNodeVersion.match(/v([0-9]+)\.[0-9]+\.[0-9]+/);
  const usingNodeMajorVersion = usingNodeMajorVersionString ? Number.parseInt(usingNodeMajorVersionString[1], 10) : null;
  if (!usingNodeMajorVersion) {
    print.title('Node Version Not Found');
    console.log('');
    console.error('Node.js is not installed or not a valid version. Please install Node.js and try again.');
    process.exit(1);
  }
  if (usingNodeMajorVersion !== nodeMajorVersion) {
    print.title('Node Version Mismatch');
    console.log('');
    console.error(`Your machine is running Node v${usingNodeMajorVersion}.`);
    console.error(`This project uses Node v${nodeMajorVersion}.`);
    console.log('Change your node version then try again.');
    console.log('');
    console.log('Use:');
    console.log(`nvm install ${nodeMajorVersion} && nvm use ${nodeMajorVersion}${nodeUpToDate ? ' && nvm alias default ' + nodeMajorVersion : ''}`);
    console.log('');
    process.exit(1);
  } else {
    console.log('...in sync!');
    console.log('');
  }
})();
