// Copyright (c) 2018, 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:async';
import 'dart:developer';

import 'package:observatory/service_io.dart';

import 'service_test_common.dart';
import 'test_helper.dart';

void testFunction() {
  debugger();
}

Future validateLocation(Location? location, Object object) async {
  if (location == null) return;
  if (location.tokenPos! < 0) return;
  if (location.script.uri == 'dart:_internal-patch/class_id_fasta.dart') {
    // Injected fields from this script cannot be reloaded.
    return;
  }

  // Ensure the script is loaded.
  final Script script = await location.script.load() as Script;

  // Use the more low-level functions.
  final line = script.tokenToLine(location.tokenPos);
  if (line == null) {
    throw 'missing location for $object in script ${script.uri}';
  }
  script.getLine(line);
  script.tokenToCol(location.tokenPos);

  // Use the helper functions.
  await location.getLine();
  await location.getColumn();
}

Future validateFieldLocation(Field field) async {
  field = await field.load() as Field;
  await validateLocation(field.location, field);
}

Future validateFunctionLocation(ServiceFunction fun) async {
  fun = await fun.load() as ServiceFunction;
  await validateLocation(fun.location, fun);
}

Future validateClassLocation(Class klass) async {
  klass = await klass.load() as Class;
  await validateLocation(klass.location, klass);

  for (Field field in klass.fields) {
    await validateFieldLocation(field);
  }
  for (ServiceFunction fun in klass.functions) {
    await validateFunctionLocation(fun);
  }
}

var tests = <IsolateTest>[
  hasStoppedAtBreakpoint,
  (Isolate isolate) async {
    // Force everything to be compiled.
    final params = {
      'reports': ['Coverage'],
      'forceCompile': true
    };
    await isolate.invokeRpcNoUpgrade('getSourceReport', params);

    // Loop over all libraries, classes, functions and fields to ensure .
    for (Library lib in isolate.libraries) {
      lib = await lib.load() as Library;

      for (Field field in lib.variables) {
        await validateFieldLocation(field);
      }
      for (ServiceFunction fun in lib.functions) {
        await validateFunctionLocation(fun);
      }
      for (Class klass in lib.classes) {
        await validateClassLocation(klass);
      }
    }
  },
];

main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
