// 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.

import 'dart:io' show Directory, Platform;

import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
import 'package:_fe_analyzer_shared/src/testing/id.dart'
    show ActualData, Id, IdKind;
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart'
    show DataInterpreter, runTests;
import 'package:front_end/src/fasta/builder/member_builder.dart';
import 'package:front_end/src/fasta/source/source_loader.dart';

import 'package:front_end/src/testing/id_testing_helper.dart';
import 'package:front_end/src/testing/id_testing_utils.dart';
import 'package:kernel/ast.dart' hide Variance;

Future<void> main(List<String> args) async {
  Directory dataDir = new Directory.fromUri(Platform.script.resolve(
      '../../../_fe_analyzer_shared/test/flow_analysis/assigned_variables/'
      'data'));
  await runTests<_Data>(dataDir,
      args: args,
      createUriForFileName: createUriForFileName,
      onFailure: onFailure,
      runTest: runTestFor<_Data>(
          const AssignedVariablesDataComputer(), [cfeNonNullableOnlyConfig]));
}

class AssignedVariablesDataComputer extends DataComputer<_Data> {
  const AssignedVariablesDataComputer();

  @override
  DataInterpreter<_Data> get dataValidator =>
      const _AssignedVariablesDataInterpreter();

  /// Function that computes a data mapping for [member].
  ///
  /// Fills [actualMap] with the data.
  @override
  void computeMemberData(
      TestConfig config,
      InternalCompilerResult compilerResult,
      Member member,
      Map<Id, ActualData<_Data>> actualMap,
      {bool? verbose}) {
    SourceMemberBuilder memberBuilder =
        lookupMemberBuilder(compilerResult, member) as SourceMemberBuilder;
    AssignedVariablesForTesting<TreeNode, VariableDeclaration>?
        assignedVariables = memberBuilder
            .dataForTesting!.inferenceData.flowAnalysisResult.assignedVariables;
    if (assignedVariables == null) return;
    member.accept(new AssignedVariablesDataExtractor(
        compilerResult, actualMap, assignedVariables));
  }
}

class AssignedVariablesDataExtractor extends CfeDataExtractor<_Data> {
  final SourceLoaderDataForTesting _sourceLoaderDataForTesting;
  final AssignedVariablesForTesting<TreeNode, VariableDeclaration>
      _assignedVariables;

  AssignedVariablesDataExtractor(InternalCompilerResult compilerResult,
      Map<Id, ActualData<_Data>> actualMap, this._assignedVariables)
      : _sourceLoaderDataForTesting =
            compilerResult.kernelTargetForTesting!.loader.dataForTesting!,
        super(compilerResult, actualMap);

  @override
  _Data computeMemberValue(Id id, Member member) {
    return new _Data(
        _convertVars(_assignedVariables.declaredAtTopLevel),
        _convertVars(_assignedVariables.readAnywhere),
        _convertVars(_assignedVariables.readCapturedAnywhere),
        _convertVars(_assignedVariables.writtenAnywhere),
        _convertVars(_assignedVariables.capturedAnywhere));
  }

  Set<String> _convertVars(Iterable<VariableDeclaration> x) =>
      x.map((e) => e.name!).toSet();

  @override
  _Data? computeNodeValue(Id id, TreeNode node) {
    switch (id.kind) {
      case IdKind.iterator:
      case IdKind.current:
      case IdKind.moveNext:
        return null;
      default:
    }
    TreeNode alias = _sourceLoaderDataForTesting.toOriginal(node);
    if (!_assignedVariables.isTracked(alias)) return null;
    return new _Data(
        _convertVars(_assignedVariables.declaredInNode(alias)),
        _convertVars(_assignedVariables.readInNode(alias)),
        _convertVars(_assignedVariables.readCapturedInNode(alias)),
        _convertVars(_assignedVariables.writtenInNode(alias)),
        _convertVars(_assignedVariables.capturedInNode(alias)));
  }
}

class _AssignedVariablesDataInterpreter implements DataInterpreter<_Data> {
  const _AssignedVariablesDataInterpreter();

  @override
  String getText(_Data actualData, [String? indentation]) {
    var parts = <String>[];
    if (actualData.declared.isNotEmpty) {
      parts.add('declared=${_setToString(actualData.declared)}');
    }
    if (actualData.read.isNotEmpty) {
      parts.add('read=${_setToString(actualData.read)}');
    }
    if (actualData.readCaptured.isNotEmpty) {
      parts.add('readCaptured=${_setToString(actualData.readCaptured)}');
    }
    if (actualData.assigned.isNotEmpty) {
      parts.add('assigned=${_setToString(actualData.assigned)}');
    }
    if (actualData.captured.isNotEmpty) {
      parts.add('captured=${_setToString(actualData.captured)}');
    }
    if (parts.isEmpty) return 'none';
    return parts.join(', ');
  }

  @override
  String? isAsExpected(_Data actualData, String? expectedData) {
    var actualDataText = getText(actualData);
    if (actualDataText == expectedData) {
      return null;
    } else {
      return 'Expected "$expectedData", got "$actualDataText"';
    }
  }

  @override
  bool isEmpty(_Data actualData) =>
      actualData.assigned.isEmpty && actualData.captured.isEmpty;

  String _setToString(Set<String> values) {
    List<String> sortedValues = values.toList()..sort();
    return '{${sortedValues.join(', ')}}';
  }
}

class _Data {
  final Set<String> declared;

  final Set<String> read;

  final Set<String> readCaptured;

  final Set<String> assigned;

  final Set<String> captured;

  _Data(this.declared, this.read, this.readCaptured, this.assigned,
      this.captured);
}
