// 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';

import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
import 'package:_fe_analyzer_shared/src/testing/id.dart' show ActualData, Id;
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/null_safety_understanding_flag.dart';
import 'package:analyzer/src/dart/analysis/testing_data.dart';
import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
import 'package:analyzer/src/util/ast_data_extractor.dart';

import '../util/id_testing_helper.dart';

main(List<String> args) async {
  Directory dataDir = Directory.fromUri(Platform.script.resolve(
      '../../../_fe_analyzer_shared/test/flow_analysis/assigned_variables/'
      'data'));
  await NullSafetyUnderstandingFlag.enableNullSafetyTypes(() {
    return runTests<_Data>(dataDir,
        args: args,
        createUriForFileName: createUriForFileName,
        onFailure: onFailure,
        runTest: runTestFor(
            const _AssignedVariablesDataComputer(), [analyzerNnbdConfig]));
  });
}

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

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

  @override
  void computeUnitData(TestingData testingData, CompilationUnit unit,
      Map<Id, ActualData<_Data>> actualMap) {
    var unitElement = unit.declaredElement!;
    var flowResult = testingData.uriToFlowAnalysisData[unitElement.source.uri]!;
    _AssignedVariablesDataExtractor(
            unitElement.source.uri, actualMap, flowResult)
        .run(unit);
  }
}

class _AssignedVariablesDataExtractor extends AstDataExtractor<_Data> {
  final FlowAnalysisDataForTesting _flowResult;

  Declaration? _currentDeclaration;

  AssignedVariablesForTesting<AstNode, PromotableElement>?
      _currentAssignedVariables;

  _AssignedVariablesDataExtractor(
      Uri uri, Map<Id, ActualData<_Data>> actualMap, this._flowResult)
      : super(uri, actualMap);

  @override
  _Data? computeNodeValue(Id id, AstNode node) {
    if (node is FunctionDeclarationStatement) {
      node = node.functionDeclaration;
    }
    var currentAssignedVariables = _currentAssignedVariables;
    if (currentAssignedVariables == null) return null;
    if (node == _currentDeclaration) {
      return _Data(
          _convertVars(currentAssignedVariables.declaredAtTopLevel),
          _convertVars(currentAssignedVariables.readAnywhere),
          _convertVars(currentAssignedVariables.readCapturedAnywhere),
          _convertVars(currentAssignedVariables.writtenAnywhere),
          _convertVars(currentAssignedVariables.capturedAnywhere));
    }
    if (!currentAssignedVariables.isTracked(node)) return null;
    return _Data(
        _convertVars(currentAssignedVariables.declaredInNode(node)),
        _convertVars(currentAssignedVariables.readInNode(node)),
        _convertVars(currentAssignedVariables.readCapturedInNode(node)),
        _convertVars(currentAssignedVariables.writtenInNode(node)),
        _convertVars(currentAssignedVariables.capturedInNode(node)));
  }

  @override
  visitConstructorDeclaration(ConstructorDeclaration node) {
    _handlePossibleTopLevelDeclaration(
        node, () => super.visitConstructorDeclaration(node));
  }

  @override
  void visitFunctionDeclaration(FunctionDeclaration node) {
    _handlePossibleTopLevelDeclaration(
        node, () => super.visitFunctionDeclaration(node));
  }

  @override
  void visitVariableDeclaration(VariableDeclaration node) {
    _handlePossibleTopLevelDeclaration(
        node, () => super.visitVariableDeclaration(node));
  }

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

  void _handlePossibleTopLevelDeclaration(
      AstNode node, void Function() callback) {
    if (_currentDeclaration == null) {
      _currentDeclaration = node as Declaration;
      _currentAssignedVariables = _flowResult.assignedVariables[node];
      callback();
      _currentDeclaration = null;
      _currentAssignedVariables = null;
    } else {
      callback();
    }
  }
}

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('read=${_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);
}
