import {promises as fsp} from 'fs';
import {join} from 'path';
import Zip from 'jszip';
import nunjucks from 'nunjucks';
import {generateLove, LoveVariant} from './love';

export async function entry(): Promise<void> {
  const themeDirectory: string = join(__dirname, '../tauon/');
  // Configure Nunjucks to use the templates for `source/tauon/`.
  nunjucks.configure(themeDirectory, {
    lstripBlocks: true,
    trimBlocks: true,
    throwOnUndefined: true
  });

  // Create a new zip archive.
  const tauonPackage: Zip = new Zip();

  // Generate the Love variants.
  const love: LoveVariant[] = generateLove();

  for (const variant of love) {
    const themeName = `Love ${variant.name.slice(0, 1).toUpperCase() +
      variant.name.slice(1)}.ttheme`;
    const outputPath: string = join(themeDirectory, themeName);

    // Render the template.
    const theme: string = nunjucks.render('love-template.ttheme', {
      love: variant,
      rgb: hexToRGB
    });

    // Write the theme to file and add it to the zip archive.
    await fsp.writeFile(outputPath, theme);
    tauonPackage.file(themeName, theme);
  }

  // Write the zip archive to file.
  const zip: Buffer = await tauonPackage.generateAsync({type: 'nodebuffer'});
  await fsp.writeFile(join(themeDirectory, 'love-tauon.zip'), zip);
}

// A quick helper function to take a 3 or 6 character hex color and have it return
// the RGB values from 0 to 256 as an `r,g,b` string since that's how Tauon
// defines its colors in the themes.
export function hexToRGB(hex: string): string {
  // If the color starts with a #, remove it.
  if (hex.startsWith('#')) {
    hex = hex.slice(1);
  }

  if (hex.length === 3) {
    return [
      parseInt(hex[0], 16),
      parseInt(hex[1], 16),
      parseInt(hex[2], 16)
    ].join(',');
  }

  if (hex.length === 6) {
    return [
      parseInt(hex.slice(0, 2), 16),
      parseInt(hex.slice(2, 4), 16),
      parseInt(hex.slice(4, 6), 16)
    ].join(',');
  }

  throw new Error(`Unsupported hex "${hex}" used`);
}

if (require.main === module) {
  entry();
}
