#!/usr/bin/env dart
// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// testing ../../../tools/addlatexhash.dart

import 'dart:io';
import 'package:path/path.dart' as path;
import '../../../tools/addlatexhash.dart';

final execDir = path.dirname(Platform.resolvedExecutable);
final dartRootDir = path.dirname(path.dirname(execDir));
final dartRootPath = dartRootDir.toString();

List<String> packageOptions() {
  if (Platform.packageConfig != null) {
    return <String>['--packages=${Platform.packageConfig}'];
  } else {
    return <String>[];
  }
}

// Check that the given ProcessResult indicates success; if so
// return the standard output, otherwise report the failure
checkAction(result, errorMessage) {
  if (result.exitCode != 0) {
    print(result.stdout);
    print(result.stderr);
    throw errorMessage;
  }
  return result.stdout;
}

oneTestCutMatch(line, re, expected) {
  var result = cutMatch(line, new RegExp(re).firstMatch(line));
  if (result != expected) {
    throw "cutMatch '$re' from '$line' yields '$result' != '$expected'";
  }
}

void testCutMatch() {
  oneTestCutMatch("test", "", "test");
  oneTestCutMatch("test", "e", "tst");
  oneTestCutMatch("test", "te", "st");
  oneTestCutMatch("test", "st", "te");
  oneTestCutMatch("test", "test", "");
}

oneTestSisp(sispFun, nameSuffix, line, expected) {
  var result = sispFun(line);
  if (result != expected) {
    throw "sispIsDart$nameSuffix '$line' yields $result";
  }
}

testSisp() {
  oneTestSisp(sispIsDartBegin, "Begin", "\\begin{dartCode}\n", true);
  oneTestSisp(sispIsDartBegin, "Begin", " \\begin{dartCode}\n", true);
  oneTestSisp(sispIsDartBegin, "Begin", "whatever else ..", false);
  oneTestSisp(sispIsDartEnd, "End", "\\end{dartCode}", true);
  oneTestSisp(sispIsDartEnd, "End", " \\end{dartCode}\t  \n", true);
  oneTestSisp(sispIsDartEnd, "End", "whatever else ..", false);
}

// Check that the hash values of paragraphs in the specially prepared
// LaTeX source 'addlatexhash_test_src.tex' are identical in groups
// of eight (so we get 8 identical hash values, then another hash
// value 8 times, etc.)
testSameHash(String tmpDirPath) {
  // file names/paths for file containing groups of 8 variants of a paragraph
  const par8timesName = "addlatexhash_test_src";
  const par8timesFileName = "$par8timesName.tex";
  final par8timesDirPath =
      path.join(dartRootDir, "tests", "standalone_2", "io");
  final par8timesPath = path.join(par8timesDirPath, par8timesFileName);
  final tmpPar8timesPath = path.join(tmpDirPath, par8timesFileName);

  // file names paths for output
  final hashName = par8timesName + "-hash";
  final hashFileName = "$hashName.tex";
  final hashPath = path.join(tmpDirPath, hashFileName);
  final listName = par8timesName + "-list";
  final listFileName = "$listName.txt";
  final listPath = path.join(tmpDirPath, listFileName);

  // dart executable
  final dartExecutable = Platform.executable;
  if (dartExecutable == "") throw "dart executable not available";

  // actions to take
  runAddHash() {
    var args = <String>[]..addAll(Platform.executableArguments);
    args.addAll([
      path.join(dartRootPath, "tools", "addlatexhash.dart"),
      tmpPar8timesPath,
      hashPath,
      listPath
    ]);
    return Process.runSync(dartExecutable, args);
  }

  // perform test
  new File(par8timesPath).copySync(tmpPar8timesPath);
  checkAction(runAddHash(), "addlatexhash.dart failed");
  var listFile = new File(listPath);
  var listLines = listFile.readAsLinesSync();
  var latestLine = null;
  var sameCount = 0;
  for (var line in listLines) {
    if (!line.startsWith("  ")) continue; // section marker
    if (line.startsWith("  %")) continue; // transformed text "comment"
    if (line != latestLine) {
      // new hash, check for number of equal hashes, then reset
      if (sameCount % 8 == 0) {
        // saw zero or more blocks of 8 identical hash values: OK
        latestLine = line;
        sameCount = 1;
      } else {
        throw "normalization failed to produce same result";
      }
    } else {
      sameCount++;
    }
  }
}

// Check that the LaTeX source transformation done by addlatexhash.dart
// does not affect the generated output, as seen via dvi2tty and diff.
// NB: Not part of normal testing (only local): latex and dvi2tty are
// not installed in the standard test environment.
testSameDVI(String tmpDirPath) {
  // file names/paths for original spec
  const specName = "dartLangSpec";
  const specFileName = "$specName.tex";
  final specDirPath = path.join(dartRootDir, "docs", "language");
  final specPath = path.join(specDirPath, specFileName);
  final tmpSpecPath = path.join(tmpDirPath, specFileName);
  const specDviFileName = "$specName.dvi";
  final specDviPath = path.join(tmpDirPath, specDviFileName);

  // file names/paths for associated sty
  const styFileName = "dart.sty";
  final styPath = path.join(specDirPath, styFileName);
  final tmpStyPath = path.join(tmpDirPath, styFileName);

  // file names paths for output
  const hashName = "dartLangSpec-hash";
  const hashFileName = "$hashName.tex";
  final hashPath = path.join(tmpDirPath, hashFileName);
  final hashDviPath = path.join(tmpDirPath, "$hashName.dvi");

  final listName = "$specName-list";
  final listFileName = "$listName.txt";
  final listPath = path.join(tmpDirPath, listFileName);

  // dart executable
  final dartExecutable = Platform.executable;
  if (dartExecutable == "") throw "dart executable not available";

  // actions to take; rely on having latex and dvi2tty in PATH
  runLatex(fileName, workingDirectory) =>
      Process.runSync("latex", [fileName], workingDirectory: workingDirectory);

  runAddHash() {
    var args = packageOptions();
    args.addAll([
      path.join(dartRootPath, "tools", "addlatexhash.dart"),
      tmpSpecPath,
      hashPath,
      listPath
    ]);
    return Process.runSync(dartExecutable, args);
  }

  runDvi2tty(dviFile) =>
      Process.runSync("dvi2tty", [dviFile], workingDirectory: tmpDirPath);

  chkDvi2tty(file, subject) =>
      checkAction(runDvi2tty(file), "dvitty on $subject failed");

  // perform test
  var renewLMHashCmd = r"\renewcommand{\LMHash}[1]{\OriginalLMHash{xxxx}}";
  new File(styPath)
      .copySync(tmpStyPath)
      .writeAsStringSync(renewLMHashCmd, mode: FileMode.append);
  new File(specPath).copySync(tmpSpecPath);

  checkAction(runAddHash(), "addlatexhash.dart failed");
  for (var i = 0; i < 5; i++) {
    checkAction(runLatex(specName, tmpDirPath), "LaTeX on spec failed");
  }
  for (var i = 0; i < 5; i++) {
    checkAction(runLatex(hashFileName, tmpDirPath), "LaTeX on output failed");
  }
  if (chkDvi2tty(specDviPath, "spec") != chkDvi2tty(hashDviPath, "output")) {
    throw "dvi2tty spec != dvitty output";
  }
}

runWithTempDir(void test(String tempDir)) {
  final tempDir = Directory.systemTemp.createTempSync("addlatexhash_test");
  try {
    test(tempDir.path);
  } finally {
    tempDir.delete(recursive: true);
  }
}

main([args]) {
  testCutMatch();
  testSisp();

  runWithTempDir(testSameHash);
  // latex and dvi2tty are not installed in the standard test environment
  if (args.length > 0 && args[0] == "local") {
    runWithTempDir(testSameDVI);
  }
}
