// Copyright (c) 2020, 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 'dart:typed_data';

import 'package:_fe_analyzer_shared/src/scanner/abstract_scanner.dart'
    show ScannerConfiguration;
import 'package:_fe_analyzer_shared/src/scanner/token.dart';
import 'package:dart_style/dart_style.dart' show DartFormatter;
import 'package:front_end/src/api_prototype/experimental_flags.dart';
import 'package:front_end/src/util/textual_outline.dart';
import 'package:testing/testing.dart'
    show
        Chain,
        ChainContext,
        Expectation,
        ExpectationSet,
        Result,
        Step,
        TestDescription;

import 'utils/kernel_chain.dart' show MatchContext;
import 'utils/suite_utils.dart';
import 'testing/environment_keys.dart';
import 'testing/folder_options.dart';

const int minSupportedMajorVersion = 2;
const int minSupportedMinorVersion = 12;

const List<Map<String, String>> EXPECTATIONS = [
  {
    "name": "ExpectationFileMismatch",
    "group": "Fail",
  },
  {
    "name": "ExpectationFileMissing",
    "group": "Fail",
  },
  {
    "name": "EmptyOutput",
    "group": "Fail",
  },
  {
    "name": "UnknownChunk",
    "group": "Fail",
  },
  {
    "name": "FormatterCrash",
    "group": "Fail",
  },
];

Future<Context> createContext(Chain suite, Map<String, String> environment) {
  return new Future.value(new Context(suite.root, environment));
}

void main([List<String> arguments = const []]) => internalMain(
      createContext,
      arguments: arguments,
      displayName: "textual outline suite",
      configurationPath: "../testing.json",
    );

class Context extends ChainContext with MatchContext {
  final SuiteFolderOptions suiteFolderOptions;
  final Map<ExperimentalFlag, bool> forcedExperimentalFlags;

  @override
  final bool updateExpectations;

  @override
  String get updateExpectationsOption =>
      '${EnvironmentKeys.updateExpectations}=true';

  @override
  bool get canBeFixWithUpdateExpectations => true;

  Context(Uri baseUri, Map<String, String> environment)
      : suiteFolderOptions = new SuiteFolderOptions(baseUri),
        updateExpectations =
            environment[EnvironmentKeys.updateExpectations] == "true",
        forcedExperimentalFlags =
            SuiteFolderOptions.computeForcedExperimentalFlags(environment);

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

  @override
  final ExpectationSet expectationSet =
      new ExpectationSet.fromJsonList(EXPECTATIONS);
}

class TextualOutline extends Step<TestDescription, TestDescription, Context> {
  const TextualOutline();

  @override
  String get name => "TextualOutline";

  @override
  Future<Result<TestDescription>> run(
      TestDescription description, Context context) async {
    FolderOptions folderOptions =
        context.suiteFolderOptions.computeFolderOptions(description);
    Map<ExperimentalFlag, bool> experimentalFlags = folderOptions
        .computeExplicitExperimentalFlags(context.forcedExperimentalFlags);
    Map<ExperimentalFlag, bool> experimentalFlagsExplicit =
        folderOptions.computeExplicitExperimentalFlags(const {});

    Uint8List bytes = new File.fromUri(description.uri).readAsBytesSync();
    for (bool modelled in [false, true]) {
      TextualOutlineInfoForTesting info = new TextualOutlineInfoForTesting();
      String? result = textualOutline(
        bytes,
        new ScannerConfiguration(
          enableExtensionMethods: isExperimentEnabled(
              ExperimentalFlag.extensionMethods,
              explicitExperimentalFlags: experimentalFlags),
          enableNonNullable: isExperimentEnabled(ExperimentalFlag.nonNullable,
              explicitExperimentalFlags: experimentalFlags),
          enableTripleShift: isExperimentEnabled(ExperimentalFlag.tripleShift,
              explicitExperimentalFlags: experimentalFlags),
        ),
        throwOnUnexpected: true,
        performModelling: modelled,
        returnNullOnError: false,
        enablePatterns: isExperimentEnabled(ExperimentalFlag.patterns,
            explicitExperimentalFlags: experimentalFlags),
        infoForTesting: info,
      );
      if (result == null) {
        return new Result(
            null, context.expectationSet["EmptyOutput"], description.uri);
      }

      bool containsUnknownChunk = info.hasUnknownChunk;
      bool tryFormat = !containsUnknownChunk;
      for (LanguageVersionToken version in info.languageVersionTokens) {
        if (version.major < minSupportedMajorVersion) {
          tryFormat = false;
        } else if (version.major == minSupportedMajorVersion &&
            version.minor < minSupportedMinorVersion) {
          tryFormat = false;
        }
      }
      dynamic formatterException;
      StackTrace? formatterExceptionSt;
      if (tryFormat) {
        try {
          List<String> experimentFlags = [];
          for (MapEntry<ExperimentalFlag, bool> entry
              in experimentalFlags.entries) {
            if (entry.value) {
              experimentFlags.add(entry.key.name);
            }
          }

          // Default to the latest language version. If the test should be at
          // an older language version, it will contain a `// @dart=x.y`
          // comment, which takes precedence over this argument.
          result = new DartFormatter(
                  languageVersion:
                      DartFormatter.latestShortStyleLanguageVersion,
                  experimentFlags: experimentFlags)
              .format(result);
        } catch (e, st) {
          formatterException = e;
          formatterExceptionSt = st;
        }
      }

      String filename = ".textual_outline.expect";
      if (modelled) {
        filename = ".textual_outline_modelled.expect";
      }

      Result<TestDescription> expectMatch =
          await context.match<TestDescription>(
              filename, result!, description.uri, description);
      if (expectMatch.outcome != Expectation.pass) return expectMatch;

      if (containsUnknownChunk) {
        return new Result(
            null, context.expectationSet["UnknownChunk"], description.uri);
      }

      if (formatterException != null && !info.hasParserErrors) {
        bool hasUnreleasedExperiment = false;
        for (MapEntry<ExperimentalFlag, bool> entry
            in experimentalFlagsExplicit.entries) {
          if (entry.value) {
            if (!entry.key.isEnabledByDefault) {
              hasUnreleasedExperiment = true;
              break;
            }
          }
        }
        if (!hasUnreleasedExperiment) {
          return new Result(null, context.expectationSet["FormatterCrash"],
              formatterException,
              trace: formatterExceptionSt);
        }
      }
    }

    return new Result.pass(description);
  }
}
