import * as rollup from "rollup";
import * as svelte from 'rollup-plugin-svelte';
import * as resolve from 'rollup-plugin-node-resolve';
import * as commonjs from 'rollup-plugin-commonjs';
import * as typescript from "rollup-plugin-typescript2";
import * as fs from "fs";
import * as copy from "rollup-plugin-copy-assets";

import {
   sass
} from 'svelte-preprocess-sass';
import {
   terser
} from 'rollup-plugin-terser';

const production = process.argv.indexOf("-d") < 0;
console.log(`Runnung in ${production ? "production" : "development"} mode!`);

let plg = [];

if (production) {
   plg.push(terser())
}

if (!fs.existsSync("build"))
   fs.mkdirSync("build");


const pages = ["Login", "Home", "User", "Public"];

let configs = pages.map(page => {
   const pageHtml = generateHtml(page)

   fs.writeFileSync(`build/${page.toLowerCase()}.html`, pageHtml);

   return <rollup.RollupOptions>{
      input: `./src/${page}/main.js`,
      output: {
         sourcemap: true,
         format: 'iife',
         name: 'app',
         file: `build/${page.toLowerCase()}/bundle.js`
      },
      watch: {
         clearScreen: false
      },
      plugins: [
         (typescript as any)({
            tsconfig: "./src/tsconfig.json"
         }),
         svelte({
            // enable run-time checks when not in production
            dev: !production,
            css: css => {
               css.write(`build/${page.toLowerCase()}/bundle.css`);
            },
            preprocess: {
               style: sass({
                  includePaths: ['src', 'node_modules']
               })
            }
         }),
         (resolve as any)(),
         (commonjs as any)(),
         ...plg
      ]
   };
})

import * as path from "path";


function cssCopyPlugin() {
   return {
      name: 'css-copy', // this name will show up in warnings and errors
      resolveId(source) {
         if (source === 'virtual-module') {
            return source; // this signals that rollup should not ask other plugins or check the file system to find this id
         }
         return null; // other ids should be handled as usually
      },
      load(id) {
         if (id === 'virtual-module') {
            return 'export default "This is virtual!"'; // the source code for "virtual-module"
         }
         return null; // other ids should be handled as usually
      }
   };
}

function generateHtml(pagename: string) {
   return `<!doctype html>
   <html lang="en">
   
   <head>
      <meta charset='utf8'>
      <meta name='viewport' content='width=device-width'>
   
      <title>OpenAuth - ${pagename}</title>
   
      <link rel='stylesheet' href='global.css'>
      <link rel='stylesheet' href='${pagename.toLowerCase()}/bundle.css'>
   </head>
   
   <body>
      <div id="content"></div>
      <script src="global.js"></script>
      <script src='${pagename.toLowerCase()}/bundle.js'></script>
      <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto" lazyload>
   </body> 
</html>`
}

var absolutePath = /^(?:\/|(?:[A-Za-z]:)?[\\|/])/;
function isAbsolute(path) {
   return absolutePath.test(path);
}

// function getAliasName(resolved, unresolved) {
//    var alias = path.basename(unresolved || resolved);
//    var ext = path.extname(resolved);
//    if (alias.endsWith(ext))
//       alias = alias.substr(0, alias.length - ext.length);
//    return alias;
// }

function relativeId(id) {
   if (typeof process === 'undefined' || !isAbsolute(id))
      return id;
   return path.relative(process.cwd(), id);
}

const tc: any = {
   enabled:
      process.env.FORCE_COLOR ||
      process.platform === "win32" ||
      (process.stdout.isTTY && process.env.TERM && process.env.TERM !== "dumb")
};
const Styles = (tc.Styles = {});
const defineProp = Object.defineProperty;

const init = (style, open, close, re) => {
   let i,
      len = 1,
      seq = [(Styles[style] = { open, close, re })];

   const fn = s => {
      if (tc.enabled) {
         for (i = 0, s += ""; i < len; i++) {
            style = seq[i];
            s =
               (open = style.open) +
               (~s.indexOf((close = style.close), 4) // skip first \x1b[
                  ? s.replace(style.re, open)
                  : s) +
               close;
         }
         len = 1;
      }
      return s
   };

   defineProp(tc, style, {
      get: () => {
         for (let k in Styles)
            defineProp(fn, k, {
               get: () => ((seq[len++] = Styles[k]), fn)
            });
         delete tc[style];
         return (tc[style] = fn)
      },
      configurable: true
   });
};

init("reset", "\x1b[0m", "\x1b[0m", /\x1b\[0m/g);
init("bold", "\x1b[1m", "\x1b[22m", /\x1b\[22m/g);
init("dim", "\x1b[2m", "\x1b[22m", /\x1b\[22m/g);
init("italic", "\x1b[3m", "\x1b[23m", /\x1b\[23m/g);
init("underline", "\x1b[4m", "\x1b[24m", /\x1b\[24m/g);
init("inverse", "\x1b[7m", "\x1b[27m", /\x1b\[27m/g);
init("hidden", "\x1b[8m", "\x1b[28m", /\x1b\[28m/g);
init("strikethrough", "\x1b[9m", "\x1b[29m", /\x1b\[29m/g);
init("black", "\x1b[30m", "\x1b[39m", /\x1b\[39m/g);
init("red", "\x1b[31m", "\x1b[39m", /\x1b\[39m/g);
init("green", "\x1b[32m", "\x1b[39m", /\x1b\[39m/g);
init("yellow", "\x1b[33m", "\x1b[39m", /\x1b\[39m/g);
init("blue", "\x1b[34m", "\x1b[39m", /\x1b\[39m/g);
init("magenta", "\x1b[35m", "\x1b[39m", /\x1b\[39m/g);
init("cyan", "\x1b[36m", "\x1b[39m", /\x1b\[39m/g);
init("white", "\x1b[37m", "\x1b[39m", /\x1b\[39m/g);
init("gray", "\x1b[90m", "\x1b[39m", /\x1b\[39m/g);
init("bgBlack", "\x1b[40m", "\x1b[49m", /\x1b\[49m/g);
init("bgRed", "\x1b[41m", "\x1b[49m", /\x1b\[49m/g);
init("bgGreen", "\x1b[42m", "\x1b[49m", /\x1b\[49m/g);
init("bgYellow", "\x1b[43m", "\x1b[49m", /\x1b\[49m/g);
init("bgBlue", "\x1b[44m", "\x1b[49m", /\x1b\[49m/g);
init("bgMagenta", "\x1b[45m", "\x1b[49m", /\x1b\[49m/g);
init("bgCyan", "\x1b[46m", "\x1b[49m", /\x1b\[49m/g);
init("bgWhite", "\x1b[47m", "\x1b[49m", /\x1b\[49m/g);

const turbocolor: any = tc;


function handleError(err, recover) {
   if (recover === void 0) { recover = false; }
   var description = err.message || err;
   if (err.name)
      description = err.name + ": " + description;
   var message = (err.plugin
      ? "(" + err.plugin + " plugin) " + description
      : description) || err;
   console.error(turbocolor.bold.red("[!] " + turbocolor.bold(message.toString())));
   if (err.url) {
      console.error(turbocolor.cyan(err.url));
   }
   if (err.loc) {
      console.error(relativeId(err.loc.file || err.id) + " (" + err.loc.line + ":" + err.loc.column + ")");
   }
   else if (err.id) {
      console.error(relativeId(err.id));
   }
   if (err.frame) {
      console.error(turbocolor.dim(err.frame));
   }
   if (err.stack) {

      //console.error(turbocolor.dim(err.stack));
   }
   console.error('');
   if (!recover)
      process.exit(1);
}
let start: [number, number];
if (process.argv.indexOf("-w") >= 0) {
   rollup.watch(configs).on("event", event => {
      if (event.code === "BUNDLE_START") {
         start = process.hrtime();
      } else if (event.code === "BUNDLE_END") {
         let diff = process.hrtime(start);
         console.log(`--- Took ${diff[0] * 1000 + diff[1] / 1000000}ms`);
      } else if (event.code === "ERROR") {
         // console.error(event.error);
         handleError(event.error, true);
      } else if (event.code === "FATAL") {
         handleError(event.error, true);
      } else {
         console.log(event);
      }
   })
} else {
   start = process.hrtime();
   Promise.all(configs.map(config => {
      return rollup.rollup(config).then((value) => {
         value.generate(config as rollup.OutputOptions)
      }).catch(err => {
         handleError(err, true);
         // console.error(err);
      })
   })).then(vals => {
      let diff = process.hrtime(start);
      console.log(`--- Took ${diff[0] * 1000 + diff[1] / 1000000}ms`);
   })
}