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

// @dart = 2.9

import 'dart:io' show Directory, File, FileSystemEntity;

import 'dart:typed_data' show Uint8List;

import 'package:_fe_analyzer_shared/src/parser/parser.dart'
    show FormalParameterKind, MemberKind, Parser;

import 'package:_fe_analyzer_shared/src/parser/listener.dart' show Listener;

import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;

import 'package:_fe_analyzer_shared/src/scanner/token.dart';

import 'package:_fe_analyzer_shared/src/scanner/utf8_bytes_scanner.dart'
    show Utf8BytesScanner;

import 'package:front_end/src/fasta/command_line_reporting.dart'
    as command_line_reporting;
import 'package:front_end/src/fasta/source/diet_parser.dart'
    show useImplicitCreationExpressionInCfe;

import 'package:kernel/kernel.dart';

import 'package:package_config/package_config.dart';

import 'package:testing/testing.dart'
    show Chain, ChainContext, Result, Step, TestDescription, runMe;

import 'testing_utils.dart' show checkEnvironment, getGitFiles;

void main([List<String> arguments = const []]) =>
    runMe(arguments, createContext, configurationPath: "../testing.json");

Future<Context> createContext(
    Chain suite, Map<String, String> environment) async {
  const Set<String> knownEnvironmentKeys = {"onlyInGit"};
  checkEnvironment(environment, knownEnvironmentKeys);

  bool onlyInGit = environment["onlyInGit"] != "false";
  return new Context(onlyInGit: onlyInGit);
}

class LintTestDescription extends TestDescription {
  @override
  final String shortName;
  @override
  final Uri uri;
  final LintTestCache cache;
  final LintListener listener;

  LintTestDescription(this.shortName, this.uri, this.cache, this.listener) {
    this.listener.description = this;
    this.listener.uri = uri;
  }

  String getErrorMessage(int offset, int squigglyLength, String message) {
    cache.source ??= new Source(cache.lineStarts, cache.rawBytes, uri, uri);
    Location location = cache.source.getLocation(uri, offset);
    return command_line_reporting.formatErrorMessage(
        cache.source.getTextLine(location.line),
        location,
        squigglyLength,
        uri.toString(),
        message);
  }
}

class LintTestCache {
  List<int> rawBytes;
  List<int> lineStarts;
  Source source;
  Token firstToken;
  PackageConfig packages;
}

class Context extends ChainContext {
  final bool onlyInGit;
  Context({this.onlyInGit});

  @override
  final List<Step> steps = const <Step>[
    const LintStep(),
  ];

  // Override special handling of negative tests.
  @override
  Result processTestResult(
      TestDescription description, Result result, bool last) {
    return result;
  }

  @override
  Stream<LintTestDescription> list(Chain suite) async* {
    Set<Uri> gitFiles;
    if (onlyInGit) {
      gitFiles = await getGitFiles(suite.uri);
    }

    Directory testRoot = new Directory.fromUri(suite.uri);
    if (await testRoot.exists()) {
      Stream<FileSystemEntity> files =
          testRoot.list(recursive: true, followLinks: false);
      await for (FileSystemEntity entity in files) {
        if (entity is! File) continue;
        String path = entity.uri.path;
        if (suite.exclude.any((RegExp r) => path.contains(r))) continue;
        if (suite.pattern.any((RegExp r) => path.contains(r))) {
          if (onlyInGit && !gitFiles.contains(entity.uri)) continue;
          Uri root = suite.uri;
          String baseName = "${entity.uri}".substring("$root".length);
          baseName = baseName.substring(0, baseName.length - ".dart".length);
          LintTestCache cache = new LintTestCache();

          yield new LintTestDescription(
            "$baseName/ExplicitType",
            entity.uri,
            cache,
            new ExplicitTypeLintListener(),
          );

          yield new LintTestDescription(
            "$baseName/ImportsTwice",
            entity.uri,
            cache,
            new ImportsTwiceLintListener(),
          );

          Uri apiUnstableUri =
              Uri.base.resolve("pkg/front_end/lib/src/api_unstable/");
          if (!entity.uri.toString().startsWith(apiUnstableUri.toString())) {
            yield new LintTestDescription(
              "$baseName/Exports",
              entity.uri,
              cache,
              new ExportsLintListener(),
            );
          }
        }
      }
    } else {
      throw "${suite.uri} isn't a directory";
    }
  }
}

class LintStep extends Step<LintTestDescription, LintTestDescription, Context> {
  const LintStep();

  @override
  String get name => "lint";

  @override
  Future<Result<LintTestDescription>> run(
      LintTestDescription description, Context context) async {
    if (description.cache.rawBytes == null) {
      File f = new File.fromUri(description.uri);
      description.cache.rawBytes = f.readAsBytesSync();

      Uint8List bytes = new Uint8List(description.cache.rawBytes.length + 1);
      bytes.setRange(
          0, description.cache.rawBytes.length, description.cache.rawBytes);

      Utf8BytesScanner scanner =
          new Utf8BytesScanner(bytes, includeComments: true);
      description.cache.firstToken = scanner.tokenize();
      description.cache.lineStarts = scanner.lineStarts;

      Uri dotPackages = description.uri.resolve(".packages");
      while (true) {
        if (new File.fromUri(dotPackages).existsSync()) {
          break;
        }
        // Stupid bailout.
        if (dotPackages.pathSegments.length < Uri.base.pathSegments.length) {
          break;
        }
        dotPackages = dotPackages.resolve("../.packages");
      }

      File dotPackagesFile = new File.fromUri(dotPackages);
      if (dotPackagesFile.existsSync()) {
        description.cache.packages = await loadPackageConfigUri(dotPackages);
      }
    }

    if (description.cache.firstToken == null) {
      return crash(description, StackTrace.current);
    }

    Parser parser = new Parser(description.listener,
        useImplicitCreationExpression: useImplicitCreationExpressionInCfe);
    parser.parseUnit(description.cache.firstToken);

    if (description.listener.problems.isEmpty) {
      return pass(description);
    }
    return fail(description, description.listener.problems.join("\n\n"));
  }
}

class LintListener extends Listener {
  List<String> problems = <String>[];
  LintTestDescription description;
  @override
  Uri uri;

  void onProblem(int offset, int squigglyLength, String message) {
    problems.add(description.getErrorMessage(offset, squigglyLength, message));
  }
}

class ExplicitTypeLintListener extends LintListener {
  List<LatestType> _latestTypes = <LatestType>[];

  @override
  void beginVariablesDeclaration(
      Token token, Token lateToken, Token varFinalOrConst) {
    if (!_latestTypes.last.type) {
      onProblem(
          varFinalOrConst.offset, varFinalOrConst.length, "No explicit type.");
    }
  }

  @override
  void handleType(Token beginToken, Token questionMark) {
    _latestTypes.add(new LatestType(beginToken, true));
  }

  @override
  void handleNoType(Token lastConsumed) {
    _latestTypes.add(new LatestType(lastConsumed, false));
  }

  @override
  void endFunctionType(Token functionToken, Token questionMark) {
    _latestTypes.add(new LatestType(functionToken, true));
  }

  @override
  void endTopLevelFields(
      Token externalToken,
      Token staticToken,
      Token covariantToken,
      Token lateToken,
      Token varFinalOrConst,
      int count,
      Token beginToken,
      Token endToken) {
    if (!_latestTypes.last.type) {
      onProblem(beginToken.offset, beginToken.length, "No explicit type.");
    }
    _latestTypes.removeLast();
  }

  @override
  void endClassFields(
      Token abstractToken,
      Token externalToken,
      Token staticToken,
      Token covariantToken,
      Token lateToken,
      Token varFinalOrConst,
      int count,
      Token beginToken,
      Token endToken) {
    if (!_latestTypes.last.type) {
      onProblem(
          varFinalOrConst.offset, varFinalOrConst.length, "No explicit type.");
    }
    _latestTypes.removeLast();
  }

  @override
  void endFormalParameter(
      Token thisKeyword,
      Token periodAfterThis,
      Token nameToken,
      Token initializerStart,
      Token initializerEnd,
      FormalParameterKind kind,
      MemberKind memberKind) {
    _latestTypes.removeLast();
  }
}

class LatestType {
  final Token token;
  bool type;

  LatestType(this.token, this.type);
}

class ImportsTwiceLintListener extends LintListener {
  Set<Uri> seenImports = new Set<Uri>();

  @override
  void endImport(Token importKeyword, Token semicolon) {
    Token importUriToken = importKeyword.next;
    String importUri = importUriToken.lexeme;
    if (importUri.startsWith("r")) {
      importUri = importUri.substring(2, importUri.length - 1);
    } else {
      importUri = importUri.substring(1, importUri.length - 1);
    }
    Uri resolved = uri.resolve(importUri);
    if (resolved.scheme == "package") {
      if (description.cache.packages != null) {
        resolved = description.cache.packages.resolve(resolved);
      }
    }
    if (!seenImports.add(resolved)) {
      onProblem(importUriToken.offset, importUriToken.lexeme.length,
          "Uri '$resolved' already imported once.");
    }
  }
}

class ExportsLintListener extends LintListener {
  @override
  void endExport(Token exportKeyword, Token semicolon) {
    Token exportUriToken = exportKeyword.next;
    String exportUri = exportUriToken.lexeme;
    if (exportUri.startsWith("r")) {
      exportUri = exportUri.substring(2, exportUri.length - 1);
    } else {
      exportUri = exportUri.substring(1, exportUri.length - 1);
    }
    Uri resolved = uri.resolve(exportUri);
    if (resolved.scheme == "package") {
      if (description.cache.packages != null) {
        resolved = description.cache.packages.resolve(resolved);
      }
    }
    onProblem(exportUriToken.offset, exportUriToken.lexeme.length,
        "Exports disallowed internally.");
  }
}
