/**
 * Copyright (c) 2017-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

require('@babel/polyfill');
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 loadConfig = require('../server/config');

const siteConfig = loadConfig(`${CWD}/website-1.x/siteConfig.js`);
const buildDir = `${CWD}/website-1.x/build`;
const docsDir = `${CWD}/docs`;

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

function generateSite() {
  shell.cd('website-1.x');
  shell.exec('yarn build', {silent: true});
}

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

describe('Build files', () => {
  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(results => {
      [
        inputMarkdownFiles,
        outputHTMLFiles,
        inputAssetsFiles,
        outputAssetsFiles,
      ] = results;
    });
  });

  afterAll(() => {
    clearBuildFolder();
  });

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

  test('Generated HTML for each Markdown resource', () => {
    const metadata = outputHTMLFiles.map(file =>
      filepath.create(file).basename(),
    );
    inputMarkdownFiles.forEach(file => {
      const data = fs.readFileSync(file, 'utf8');
      const frontmatter = fm(data);
      expect(metadata).toContain(`${frontmatter.attributes.id}.html`);
    });
  });

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

  test('Copied assets from /docs/assets', () => {
    const metadata = outputAssetsFiles.map(file =>
      filepath.create(file).basename(),
    );
    inputAssetsFiles.forEach(file => {
      const path = filepath.create(file);
      expect(metadata).toContain(path.basename());
    });
  });
});

describe('Build files but skip next release', () => {
  beforeAll(() => {
    shell.cd('website-1.x');
    shell.exec('yarn build --skip-next-release', {silent: true});
  });

  afterAll(() => {
    clearBuildFolder();
  });

  test('Did not generate HTML files from markdown files for next release', () => {
    expect(
      glob.sync(`${buildDir}/${siteConfig.projectName}/docs/**/next`).length,
    ).toBe(0);
  });
});
