// Copyright (c) 2017, 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.

import 'dart:io';

import 'package:args/args.dart';
import 'package:status_file/canonical_status_file.dart';
import 'package:status_file/status_file.dart' as status_file;
import 'package:status_file/status_file_linter.dart';
import 'package:status_file/utils.dart';

ArgParser buildParser() {
  var parser = ArgParser();
  parser.addFlag("check-for-disjunctions",
      negatable: false,
      defaultsTo: false,
      help: "Warn if a status header expression contains '||'.");
  parser.addFlag("text",
      abbr: "t",
      negatable: false,
      defaultsTo: false,
      help: "Lint text passed in stdin.");
  parser.addFlag("help",
      abbr: "h",
      negatable: false,
      defaultsTo: false,
      help: "Show help and commands for this tool.");
  return parser;
}

void printHelp(ArgParser parser) {
  print("Usage: 'dart status_file/bin/lint.dart <path>' or 'dart "
      "status_file/bin/lint.dart -t <input>' for text input.");
  print(parser.usage);
}

void main(List<String> arguments) {
  var parser = buildParser();
  var results = parser.parse(arguments);
  if (results["help"]) {
    printHelp(parser);
    return;
  }
  bool checkForDisjunctions = results["check-for-disjunctions"];
  bool usePipe = results["text"];
  if (usePipe) {
    lintStdIn(checkForDisjunctions: checkForDisjunctions);
  } else {
    if (results.rest.length != 1) {
      printHelp(parser);
      exit(1);
    }
    lintPath(results.rest.first, checkForDisjunctions: checkForDisjunctions);
  }
}

void lintStdIn({bool checkForDisjunctions = false}) {
  var strings = <String>[];
  try {
    while (true) {
      var readString = stdin.readLineSync();
      if (readString == null) break;
      strings.add(readString);
    }
  } on StdinException {
    // I do not know why this happens.
  }
  if (!lintText(strings)) {
    exit(1);
  }
}

void lintPath(path, {bool checkForDisjunctions = false}) {
  var filesWithErrors = <String>[];
  if (FileSystemEntity.isFileSync(path)) {
    if (!lintFile(path, checkForDisjunctions: checkForDisjunctions)) {
      filesWithErrors.add(path);
    }
  } else if (FileSystemEntity.isDirectorySync(path)) {
    Directory(path).listSync(recursive: true).forEach((entry) {
      if (!canLint(entry.path)) {
        return;
      }
      if (!lintFile(entry.path, checkForDisjunctions: checkForDisjunctions)) {
        filesWithErrors.add(entry.path);
      }
    });
  }
  if (filesWithErrors.isNotEmpty) {
    print("File output does not match how status files should be formatted.");
    print("Fix these issues with:");
    print("dart ${Platform.script.resolve("normalize.dart").path} -w \\");
    print(filesWithErrors.join(" \\\n"));
    exit(1);
  }
}

bool lintText(List<String> text, {bool checkForDisjunctions = false}) {
  try {
    var statusFile = StatusFile.parse("stdin", text);
    return lintStatusFile(statusFile,
        checkForDisjunctions: checkForDisjunctions);
  } on status_file.SyntaxError {
    stderr.writeln("Could not parse stdin.");
  }
  return false;
}

bool lintFile(String path, {bool checkForDisjunctions = false}) {
  try {
    var statusFile = StatusFile.read(path);
    return lintStatusFile(statusFile,
        checkForDisjunctions: checkForDisjunctions);
  } on status_file.SyntaxError catch (error) {
    stderr.writeln("Could not parse $path:\n$error");
  }
  return false;
}

bool lintStatusFile(StatusFile statusFile,
    {bool checkForDisjunctions = false}) {
  var lintingErrors =
      lint(statusFile, checkForDisjunctions: checkForDisjunctions);
  if (lintingErrors.isEmpty) {
    print("${statusFile.path}\n Status file passed all tests");
    print("");
    return true;
  }
  if (statusFile.path.isNotEmpty) {
    print(statusFile.path);
  }
  var errors = lintingErrors.toList();
  errors.sort((a, b) => a.lineNumber.compareTo((b.lineNumber)));
  errors.forEach(print);
  print("");
  return false;
}
