#! /usr/bin/env node

'use strict';

const commandLineArgs = require('command-line-args');
const path = require('path');
const fs = require('fs');
const shell = require('shelljs');
const rootPath = __dirname.split('node_modules')[0];
const packagePath = rootPath + 'package.json';
const pkg = require(packagePath);


// Parse inline arguments
const optionDefinitions = [
  { name: 'dev', alias: 'd', type: Boolean },
  { name: 'ignoreversion', type: Boolean },
  { name: 'nooffline', type: Boolean },
  { name: 'player', type: Boolean},
  { name: 'prod', type: Boolean },
];
const options = commandLineArgs(optionDefinitions);

const destination = pkg.config.destination;
const version = pkg.version;



/**
 * Copies offline support service woker over to the application.
 */
function copyOfflineSupportWorker() {
  try {
    const commonStaticResources = [
      './',
      './index.html',
      './enplug-offline-worker.js'
    ];

    let indexFilePath = path.join(rootPath, 'dist/index.html');

    let configPath = path.join(rootPath, 'offline.config.json');
    let srcFilePath = path.join(__dirname, './templates/enplug-offline-worker.js');
    let destFilePathDist = path.join(rootPath, 'dist/enplug-offline-worker.js');
    let destFilePathSrc = path.join(rootPath, 'src/enplug-offline-worker.js');
    if (options.player) {
      srcFilePath = path.join(__dirname, './templates/enplug-player-offline-worker.js');
    }

    let offlineConfig = require(configPath);
    offlineConfig.appName = `${pkg.name}`;
    offlineConfig.cacheVersion = `${pkg.name}-${pkg.version.replace(/\./g, '-')}`;

    offlineConfig.staticResources = offlineConfig.staticResources || [];
    offlineConfig.staticResources = offlineConfig.staticResources.concat(commonStaticResources).sort();
    offlineConfig.staticResources = offlineConfig.staticResources.filter(function (item, position) {
      return offlineConfig.staticResources.indexOf(item) === position;
    });
    offlineConfig.noCacheUrls = offlineConfig.noCacheUrls || [];

    fs.readFile(indexFilePath, 'utf8', (err, indexFile) => {
      // Generate .css and .js static resources array.
      const reJs = new RegExp(/src="(.*?\.js)"/mg);
      const reCss = new RegExp(/href="([^"]*?\.css)"/mg);

      let srcJsMatch = reJs.exec(indexFile);
      while (srcJsMatch != null) {
        let src = srcJsMatch[1]
        // Add local resources and enplug.com files.
        if ((src.indexOf('//') !== 0 && src.indexOf('http') !== 0) ||
            (src.indexOf('enplug.com') >= 0) ||
            (src.indexOf('enplug.in'))) {
          offlineConfig.staticResources.push(src);
        }
        srcJsMatch = reJs.exec(indexFile);
      }

      let srcCssMatch = reCss.exec(indexFile);
      while (srcCssMatch != null) {
        let src = srcCssMatch[1]
        // Add local resources and enplug.com files.
        if ((src.indexOf('//') !== 0 && src.indexOf('http') !== 0) ||
            (src.indexOf('enplug.com') >= 0) ||
            (src.indexOf('enplug.in'))) {
          offlineConfig.staticResources.push(src);
        }
        srcCssMatch = reCss.exec(indexFile);
      }

      console.log('Following static resources have been found:\n', offlineConfig.staticResources);

      fs.readFile(srcFilePath, 'utf8', (err, data) => {
        if (err) {
          return console.log('Unable to read common offline file. Please check if @enplug/sdk-player is installed.');
        }
        data = data.replace(/<% config %>/g, JSON.stringify(offlineConfig));
        var offlineServiceWorkerFile = data.replace(/<% app_name %>/g, pkg.name);
        fs.writeFile(destFilePathDist, offlineServiceWorkerFile, 'utf8', (err) => {
           if (err) {
             return console.log('Unable to write a common offline service worker file');
           }
        });
        fs.writeFile(destFilePathSrc, offlineServiceWorkerFile, 'utf8', (err) => {
          if (err) {
            return console.log('Unable to write a common offline service worker file');
          }
        });
      });
    });
  } catch (e) {
    console.warn(`Unable to copy offline support service worker. Please check whether offline.config.json exists.`);
  }
}


function runBuild() {
  let baseHref = path.posix.join('/', destination, version, '/');
  if (options.ignoreversion) {
    baseHref = path.posix.join('/', destination, '/');
  }
  let command = 'ng build --base-href ' + baseHref;
  if (!options.dev) {
    command += ' --prod'; // minify
  }
  if (options.prod) {
    command += ' --env=prod'; // set env to prod
  }

  console.log(`Running command: ${command}`);
  shell.exec(command);
}

runBuild();
if (!options.nooffline) {
  copyOfflineSupportWorker();
}
