// 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:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/kernel/element_map.dart';
import 'package:compiler/src/kernel/kernel_backend_strategy.dart';
import 'package:compiler/src/resolution/access_semantics.dart';
import 'package:compiler/src/resolution/send_structure.dart';
import 'package:compiler/src/tree/nodes.dart' as ast;
import 'package:expect/expect.dart';
import 'package:kernel/ast.dart' as ir;
import '../equivalence/id_equivalence.dart';
import '../equivalence/id_equivalence_helper.dart';

const List<String> dataDirectories = const <String>[
  '../closure/data',
  '../inference/data',
  '../jumps/data',
];

main(List<String> args) {
  asyncTest(() async {
    for (String path in dataDirectories) {
      Directory dataDir = new Directory.fromUri(Platform.script.resolve(path));
      await for (FileSystemEntity entity in dataDir.list()) {
        if (args.isNotEmpty && !args.contains(entity.uri.pathSegments.last)) {
          continue;
        }
        print('Checking ${entity.uri}');
        String annotatedCode =
            await new File.fromUri(entity.uri).readAsString();
        IdData data1 = await computeData(
            annotatedCode, computeAstMemberData, compileFromSource,
            options: [Flags.disableTypeInference, stopAfterTypeInference]);
        IdData data2 = await computeData(
            annotatedCode, computeIrMemberData, compileFromDill,
            options: [Flags.disableTypeInference, stopAfterTypeInference]);
        data1.actualMap.forEach((Id id, ActualData actualData1) {
          IdValue value1 = actualData1.value;
          IdValue value2 = data2.actualMap[id]?.value;
          if (value1 != value2) {
            reportHere(data1.compiler.reporter, actualData1.sourceSpan,
                '$id: from source:${value1},from dill:${value2}');
            print('--annotations diff----------------------------------------');
            print(data1.computeDiffCodeFor(data2));
            print('----------------------------------------------------------');
          }
          Expect.equals(value1, value2, 'Value mismatch for $id');
        });
        data2.actualMap.forEach((Id id, ActualData actualData2) {
          IdValue value2 = actualData2.value;
          IdValue value1 = data1.actualMap[id]?.value;
          if (value1 != value2) {
            reportHere(data2.compiler.reporter, actualData2.sourceSpan,
                '$id: from source:${value1},from dill:${value2}');
            print('--annotations diff----------------------------------------');
            print(data1.computeDiffCodeFor(data2));
            print('----------------------------------------------------------');
          }
          Expect.equals(value1, value2, 'Value mismatch for $id');
        });
      }
    }
  });
}

/// Compute a descriptive mapping of the [Id]s in [_member] as a
/// [MemberElement].
///
/// Fills [actualMap] with the data and [sourceSpanMap] with the source spans
/// for the data origin.
void computeAstMemberData(
    Compiler compiler, MemberEntity _member, Map<Id, ActualData> actualMap,
    {bool verbose: false}) {
  MemberElement member = _member;
  ResolvedAst resolvedAst = member.resolvedAst;
  new ResolvedAstComputer(compiler.reporter, actualMap, resolvedAst).run();
}

/// Mixin used for computing a descriptive mapping of the [Id]s in a member.
class ComputerMixin {
  String computeMemberName(String className, String memberName) {
    if (className != null) {
      return 'member:$className.$memberName';
    }
    return 'member:$memberName';
  }

  String computeLocalName(String localName) {
    return 'local:$localName';
  }

  String computeGetName(String propertyName) {
    return 'get:$propertyName';
  }

  String computeInvokeName(String propertyName) {
    return 'invoke:$propertyName';
  }

  String computeSetName(String propertyName) {
    return 'set:$propertyName';
  }

  String get loopName => 'loop';

  String get gotoName => 'goto';

  String get switchName => 'switch';

  String get switchCaseName => 'case';

  String get labelName => 'label';
}

/// AST visitor for computing a descriptive mapping of the [Id]s in a member.
class ResolvedAstComputer extends AstDataExtractor with ComputerMixin {
  ResolvedAstComputer(DiagnosticReporter reporter,
      Map<Id, ActualData> actualMap, ResolvedAst resolvedAst)
      : super(reporter, actualMap, resolvedAst);

  @override
  String computeNodeValue(Id id, ast.Node node, AstElement element) {
    if (element != null && element.isLocal) {
      return computeLocalName(element.name);
    }
    if (node is ast.Loop) {
      return loopName;
    } else if (node is ast.GotoStatement) {
      return gotoName;
    } else if (node is ast.SwitchStatement) {
      return switchName;
    } else if (node is ast.SwitchCase) {
      return switchCaseName;
    } else if (node is ast.LabeledStatement) {
      return labelName;
    }

    dynamic sendStructure;
    if (node is ast.Send) {
      sendStructure = elements.getSendStructure(node);
      if (sendStructure == null) return null;

      String getDynamicName() {
        switch (sendStructure.semantics.kind) {
          case AccessKind.PARAMETER:
          case AccessKind.FINAL_PARAMETER:
          case AccessKind.LOCAL_VARIABLE:
          case AccessKind.FINAL_LOCAL_VARIABLE:
          case AccessKind.LOCAL_FUNCTION:
            return sendStructure.semantics.element.name;
          case AccessKind.THIS_PROPERTY:
          case AccessKind.DYNAMIC_PROPERTY:
            DynamicAccess access = sendStructure.semantics;
            return access.name.text;
          default:
            return null;
        }
      }

      switch (sendStructure.kind) {
        case SendStructureKind.GET:
          String dynamicName = getDynamicName();
          if (dynamicName != null) return computeGetName(dynamicName);
          break;
        case SendStructureKind.BINARY:
          return computeInvokeName(sendStructure.operator.selectorName);
        case SendStructureKind.EQUALS:
          return computeInvokeName('==');
        case SendStructureKind.NOT_EQUALS:
          return computeInvokeName('==');
        case SendStructureKind.INVOKE:
          String dynamicName = getDynamicName();
          if (dynamicName != null) return computeInvokeName(dynamicName);
          break;
        case SendStructureKind.SET:
          String dynamicName = getDynamicName();
          if (dynamicName != null) return computeSetName(dynamicName);
          break;
        case SendStructureKind.PREFIX:
        case SendStructureKind.POSTFIX:
        case SendStructureKind.COMPOUND:
          String dynamicName = getDynamicName();
          if (dynamicName != null) {
            if (id.kind == IdKind.update) {
              return computeSetName(dynamicName);
            } else if (id.kind == IdKind.invoke) {
              return computeInvokeName(
                  sendStructure.operator.binaryOperator.name);
            } else {
              return computeGetName(dynamicName);
            }
          }
          break;
        default:
      }
    }
    if (sendStructure != null) {
      return '<unknown:$node (${node.runtimeType}) $sendStructure>';
    }
    return '<unknown:$node (${node.runtimeType})>';
  }

  @override
  String computeElementValue(Id id, AstElement element) {
    return computeMemberName(element.enclosingClass?.name, element.name);
  }
}

/// Compute a descriptive mapping of the [Id]s in [member] as a kernel based
/// member.
///
/// Fills [actualMap] with the data and [sourceSpanMap] with the source spans
/// for the data origin.
void computeIrMemberData(
    Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
    {bool verbose: false}) {
  KernelBackendStrategy backendStrategy = compiler.backendStrategy;
  KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
  MemberDefinition definition = elementMap.getMemberDefinition(member);
  assert(
      definition.kind == MemberKind.regular ||
          definition.kind == MemberKind.constructor,
      failedAt(member, "Unexpected member definition $definition"));
  new IrComputer(compiler.reporter, actualMap).run(definition.node);
}

/// IR visitor for computing a descriptive mapping of the [Id]s in a member.
class IrComputer extends IrDataExtractor with ComputerMixin {
  IrComputer(DiagnosticReporter reporter, Map<Id, ActualData> actualMap)
      : super(reporter, actualMap);

  @override
  String computeNodeValue(Id id, ir.TreeNode node) {
    if (node is ir.VariableDeclaration) {
      return computeLocalName(node.name);
    } else if (node is ir.FunctionDeclaration) {
      return computeLocalName(node.variable.name);
    } else if (node is ir.FunctionExpression) {
      return computeLocalName('');
    } else if (node is ir.MethodInvocation) {
      return computeInvokeName(node.name.name);
    } else if (node is ir.PropertyGet) {
      return computeGetName(node.name.name);
    } else if (node is ir.PropertySet) {
      return computeSetName(node.name.name);
    } else if (node is ir.VariableGet) {
      return computeGetName(node.variable.name);
    } else if (node is ir.VariableSet) {
      return computeSetName(node.variable.name);
    } else if (node is ir.DoStatement) {
      return loopName;
    } else if (node is ir.ForStatement) {
      return loopName;
    } else if (node is ir.ForInStatement) {
      return loopName;
    } else if (node is ir.WhileStatement) {
      return loopName;
    } else if (node is ir.BreakStatement) {
      return gotoName;
    } else if (node is ir.ContinueSwitchStatement) {
      return gotoName;
    } else if (node is ir.SwitchStatement) {
      return switchName;
    } else if (node is ir.SwitchCase) {
      return switchCaseName;
    } else if (node is ir.LabeledStatement) {
      return labelName;
    }
    return '<unknown:$node (${node.runtimeType})>';
  }

  @override
  String computeMemberValue(Id id, ir.Member member) {
    return computeMemberName(member.enclosingClass?.name, member.name.name);
  }
}
