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

// @dart = 2.9

import 'package:dev_compiler/src/kernel/expression_compiler.dart';
import 'package:front_end/src/api_unstable/ddc.dart';
import 'package:front_end/src/compute_platform_binaries_location.dart';
import 'package:kernel/ast.dart';
import 'package:kernel/binary/ast_from_binary.dart';
import 'package:kernel/src/printer.dart';
import 'package:test/test.dart';

/// Verbose mode for debugging
bool get verbose => false;

Uri get sdkRoot => computePlatformBinariesLocation();
Uri get sdkSummaryPath => sdkRoot.resolve('ddc_sdk.dill');
Uri get librariesPath => sdkRoot.resolve('lib/libraries.json');

void main(List<String> args) {
  test('Offsets are present on scoping nodes in SDK', () async {
    var entity = StandardFileSystem.instance.entityForUri(sdkSummaryPath);
    var bytes = await entity.readAsBytes();

    var component = Component();
    BinaryBuilderWithMetadata(bytes, disableLazyReading: true)
        .readComponent(component, checkCanonicalNames: true, createView: true);

    for (var lib in component.libraries) {
      ScopeOffsetValidator.validate(lib);
    }
  });
}

class ScopeOffsetValidator extends Visitor<void> with VisitorVoidMixin {
  int classCount = 0;
  int memberCount = 0;
  int blockCount = 0;

  ScopeOffsetValidator._();

  static void validate(Library library) {
    var validator = ScopeOffsetValidator._();
    validator.visitLibrary(library);
    expect(validator.classCount + validator.memberCount, greaterThan(0),
        reason: 'Validation was not empty');
    expect(validator.blockCount, equals(0),
        reason: 'SDK dill only contains outlines');
  }

  @override
  void defaultTreeNode(Node node) {
    node.visitChildren(this);
  }

  @override
  void visitClass(Class cls) {
    classCount++;
    expect(
        cls,
        const TypeMatcher<Class>()
            .having((c) => c.fileOffset, '${cls.name} : fileOffset',
                isNot(equals(-1)))
            .having((c) => c.fileEndOffset, '${cls.name} : fileEndOffset',
                isNot(equals(-1))));

    super.visitClass(cls);
  }

  @override
  void defaultMember(Member member) {
    // exclude code that does not correspond to a dart source
    // location we can set a breakpoint on.
    var noBreakPointPossible = (member is Constructor)
        ? member.isSynthetic
        : (member is Procedure)
            ? member.isNoSuchMethodForwarder ||
                member.isAbstract ||
                member.isForwardingStub ||
                member.stubKind == ProcedureStubKind.ConcreteMixinStub
            : (member is Field)
                ? member.name.text.contains(redirectingName)
                : false;

    if (!noBreakPointPossible) {
      memberCount++;
      expect(
          member,
          const TypeMatcher<Member>()
              .having(
                  (c) => c.fileOffset,
                  '${member.enclosingClass}.${member.name} : fileOffset',
                  isNot(equals(-1)))
              .having(
                  (c) => c.fileEndOffset,
                  '${member.enclosingClass}.${member.name} : fileEndOffset',
                  isNot(equals(-1))));

      super.defaultMember(member);
    }
  }

  @override
  void visitFunctionNode(FunctionNode fun) {
    expect(
        fun,
        const TypeMatcher<FunctionNode>()
            .having(
                (c) => c.fileOffset,
                '${fun.parent.toText(astTextStrategyForTesting)} : fileOffset',
                isNot(equals(-1)))
            .having(
                (c) => c.fileEndOffset,
                '${fun.parent.toText(astTextStrategyForTesting)} : fileEndOffset',
                isNot(equals(-1))));

    super.visitFunctionNode(fun);
  }

  @override
  void visitBlock(Block block) {
    blockCount++;
    expect(
        block,
        const TypeMatcher<FunctionNode>().having(
            (c) => c.fileOffset,
            '${block.toText(astTextStrategyForTesting)} : fileOffset',
            isNot(equals(-1))));

    var fileEndOffset = FileEndOffsetCalculator.calculateEndOffset(block);
    expect(fileEndOffset, isNot(equals(-1)),
        reason: '${block.toText(astTextStrategyForTesting)} : fileOffset');

    super.visitBlock(block);
  }
}
