const filepath = require('filepath');
const fm = require('front-matter');
const fs = require('fs-extra');
const glob = require('glob-promise');
const rimraf = require('rimraf');
const shell = require('shelljs');

const CWD = process.cwd();

const siteConfig = require(CWD + '/website/siteConfig.js');
const buildDir = CWD + '/website/build';
const docsDir = CWD + '/docs';
const staticCSSDir = CWD + '/website/static/css';

let inputMarkdownFiles = [];
let inputAssetsFiles = [];
let outputHTMLFiles = [];
let outputAssetsFiles = [];

function generateSite() {
  shell.cd('website');
  shell.exec('yarn build');
}

function clearBuildFolder() {
  return rimraf(buildDir);
}

beforeEach(() => {
  shell.cd(CWD);
});

beforeAll(() => {
  generateSite();
  return Promise.all([
    glob(docsDir + '/**/*.md'),
    glob(buildDir + '/' + siteConfig.projectName + '/docs/*.html'),
    glob(docsDir + '/assets/*'),
    glob(buildDir + '/' + siteConfig.projectName + '/img/*'),
  ]).then(function(results) {
    inputMarkdownFiles = results[0];
    outputHTMLFiles = results[1];
    inputAssetsFiles = results[2];
    outputAssetsFiles = results[3];
    return;
  });
});

function afterAll() {
  clearBuildFolder();
}

test('Build folder exists', function() {
  return fs.stat(buildDir).then(function(status) {
    expect(status.isDirectory()).toBeTruthy();
  });
});

test('Generated HTML for each Markdown resource', function() {
  let metadata = [];
  outputHTMLFiles.forEach(function(file) {
    const path = filepath.create(file);
    metadata.push(path.basename());
  });
  inputMarkdownFiles.forEach(function(file) {
    const path = filepath.create(file);
    const data = fs.readFileSync(file, 'utf8');
    const frontmatter = fm(data);
    expect(metadata).toContain(frontmatter.attributes.id + '.html');
  });
});

test('Generated table of contents', function() {
  outputHTMLFiles.forEach(function(file) {
    const fileContents = fs.readFileSync(file, 'utf8');
    expect(fileContents).not.toContain('<AUTOGENERATED_TABLE_OF_CONTENTS>');
  });
});

test('Concatenated CSS files', function() {
  return Promise.all([
    glob(staticCSSDir + '/*.css'),
    fs.readFile(
      buildDir + '/' + siteConfig.projectName + '/css/main.css',
      'utf8'
    ),
  ]).then(function(results) {
    const inputFiles = results[0];
    const outputFile = results[1];
    inputFiles.forEach(function(file) {
      const contents = fs.readFileSync(file, 'utf8');
      expect(outputFile).toContain(contents);
    });
  });
});

test('Copied assets from /docs/assets', function() {
  let metadata = [];
  outputAssetsFiles.forEach(function(file) {
    const path = filepath.create(file);
    metadata.push(path.basename());
  });
  inputAssetsFiles.forEach(function(file) {
    const path = filepath.create(file);
    expect(metadata).toContain(path.basename());
  });
});