import * as fs from 'fs';
import * as os from 'os';
import * as crypto from 'crypto';
import { execSync } from 'child_process';
const colors = require('colors/safe');

const action = process.argv[2];
const subaction = process.argv[3];

const isApple = (process.platform === 'darwin');
const isIntel = os.cpus()[0].model.startsWith('Intel');
const isAppleSilicon = os.cpus()[0].model.startsWith('Apple M');

if (isApple) {
  try {
    execSync('xcrun --version', { stdio: [] });
  } catch (e) {
    console.error(colors.red(`This module requires xcode-select to be correctly configured in your environment.\n` +
                  `Please make sure to run 'xcode-select --install' before proceeding.\n` +
                  `Original error: ${e.stderr.toString()}`))
    process.exit(1);
  }
}

if (action === 'set-path') {

  const gypBinding = JSON.parse(fs.readFileSync('binding.gyp', 'utf8'));
  const libs = gypBinding.targets[0].libraries;
  const revert = subaction && subaction === 'revert';
  for (let i = 0; i < libs.length; ++i) {
    const split = libs[i].split('/');
    if (!revert) {
      libs[i] = __dirname + '/fourq-shared/' + split[split.length-1];  
    } else {
      libs[i] = split[split.length-1];
    }
  }
  fs.writeFileSync('binding.gyp', JSON.stringify(gypBinding, null, 2));

} else if (action === 'make') {

  // Set random public key for serverside unknowability feature
  const randBytes32 = crypto.randomBytes(32);
  const pubkeyStrings: string[] = [];
  randBytes32.forEach((v, i) => {
    let hex = v.toString(16); if (hex.length === 1) { hex += '0'; }
    pubkeyStrings[i] = '\\x' + hex;
  });
  const pubkeyString = pubkeyStrings.join('');
  let ssuContent = fs.readFileSync('./features/serverside_unknowability.cc', 'utf8');
  ssuContent = ssuContent.split(' = "')[0] + ' = "' + pubkeyString + '";';
  fs.writeFileSync('./features/serverside_unknowability.cc', ssuContent, 'utf8');

  // Build FourQ lib (https://github.com/microsoft/FourQlib)
  if (isApple && isIntel) { // only for intel macs (Apple arm-based can enjoy FourQ endomorphisms)
    execSync('cd FourQlib/FourQ_64bit_and_portable; make ARCH=x64 GENERIC=TRUE SHARED_LIB=TRUE; cp ../../FourQlib/FourQ_64bit_and_portable/*.so ../../fourq-shared/');  
    execSync('cd fourq-shared; install_name_tool -id "'+__dirname+'/fourq-shared/libFourQ.so" libFourQ.so');
  } else if (isApple && isAppleSilicon) {
    execSync('cd FourQlib/FourQ_64bit_and_portable; make ARCH=APPLE_ARM64 SHARED_LIB=TRUE; cp ../../FourQlib/FourQ_64bit_and_portable/*.so ../../fourq-shared/');
    execSync('cd fourq-shared; install_name_tool -id "'+__dirname+'/fourq-shared/libFourQ.so" libFourQ.so');
  } else if (process.arch === 'arm64') {
    execSync('cd FourQlib/FourQ_64bit_and_portable; make ARCH=ARM64 SHARED_LIB=TRUE; cp ../../FourQlib/FourQ_64bit_and_portable/*.so ../../fourq-shared/');
  } else {
    execSync('cd FourQlib/FourQ_64bit_and_portable; make ARCH=x64 GENERIC=TRUE SHARED_LIB=TRUE; cp ../../FourQlib/FourQ_64bit_and_portable/*.so ../../fourq-shared/');
  }

}
