/* @flow */
import path from 'path';

import {describe, it} from 'mocha';
import {assert} from 'chai';
import { fs } from 'mz';

import {
  minimalAddonPath, fakeFirefoxPath,
  withTempAddonDir, execWebExt, reportCommandErrors,
} from './common';

const EXPECTED_MESSAGE = 'Fake Firefox binary executed correctly.';

describe('web-ext run', () => {

  it('accepts: --no-reload --watch-file --watch-files --source-dir ' +
    'SRCDIR --firefox FXPATH --watch-ignored',
     () => withTempAddonDir(
       {addonPath: minimalAddonPath},
       (srcDir) => {
         const watchedFile = path.join(srcDir, 'watchedFile.txt');
         const watchedFilesArr = ['watchedFile1', 'watchedFile2'].map(
           (file) => path.join(srcDir, file)
         );
         const watchIgnoredArr = ['ignoredFile1.txt', 'ignoredFile2.txt'].map(
           (file) => path.join(srcDir, file)
         );
         const watchIgnoredFile = path.join(srcDir, 'ignoredFile3.txt');

         fs.writeFileSync(watchedFile, '');
         watchedFilesArr.forEach((file) => fs.writeFileSync(file, ''));
         watchIgnoredArr.forEach((file) => fs.writeFileSync(file, ''));
         fs.writeFileSync(watchIgnoredFile, '');

         const argv = [
           'run', '--verbose', '--no-reload',
           '--source-dir', srcDir,
           '--watch-file', watchedFile,
           '--watch-files', ...watchedFilesArr,
           '--firefox', fakeFirefoxPath,
           '--watch-ignored', ...watchIgnoredArr,
           '--watch-ignored', watchIgnoredFile,
         ];
         const spawnOptions = {
           env: {
             PATH: process.env.PATH,
             EXPECTED_MESSAGE,
             addonPath: srcDir,
             // Add an environment var unrelated to the executed command to
             // ensure we do clear the environment vars from them before
             // yargs is validation the detected cli and env options.
             // (See #793).
             WEB_EXT_API_KEY: 'fake-api-key',
             // Also include an environment var that misses the '_' separator
             // between envPrefix and option name.
             WEB_EXTAPI_SECRET: 'fake-secret',
           },
         };

         const cmd = execWebExt(argv, spawnOptions);

         return cmd.waitForExit.then(({exitCode, stdout, stderr}) => {
           if (stdout.indexOf(EXPECTED_MESSAGE) < 0) {
             reportCommandErrors({
               argv,
               exitCode,
               stdout,
               stderr,
             }, 'The fake Firefox binary has not been executed');
           } else if (exitCode !== 0) {
             reportCommandErrors({
               argv,
               exitCode,
               stdout,
               stderr,
             });
           }
         });
       }));

  it('should not accept: --watch-file <directory>', () => withTempAddonDir(
    {addonPath: minimalAddonPath},
    (srcDir) => {
      const argv = [
        'run', '--verbose',
        '--source-dir', srcDir,
        '--watch-file', srcDir,
        '--firefox', fakeFirefoxPath,
      ];

      const spawnOptions = {
        env: {
          PATH: process.env.PATH,
          addonPath: srcDir,
        },
      };

      return execWebExt(argv, spawnOptions).waitForExit.then(({stdout}) => {
        assert.match(
          stdout,
          /Invalid --watch-file value: .+ is not a file./
        );
      });
    }));

  it('should not accept: --target INVALIDTARGET', async () => {
    const argv = [
      'run',
      '--target', 'firefox-desktop',
      '--target', 'firefox-android',
      '--target', 'chromium',
      '--target', 'not-supported',
    ];

    return execWebExt(argv, {}).waitForExit.then(({exitCode, stderr}) => {
      assert.notEqual(exitCode, 0);
      assert.match(stderr, /Invalid values/);
      assert.match(stderr, /Given: "not-supported"/);
    });
  });
});
