// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:file/file.dart';

import 'package:vm_service/vm_service.dart';

import '../src/common.dart';
import 'test_data/basic_project.dart';
import 'test_data/tests_project.dart';
import 'test_driver.dart';
import 'test_utils.dart';

void batch1() {
  final BasicProject project = BasicProject();
  late Directory tempDir;
  late FlutterRunTestDriver flutter;

  Future<void> initProject() async {
    tempDir = createResolvedTempDirectorySync('run_expression_eval_test.');
    await project.setUpIn(tempDir);
    flutter = FlutterRunTestDriver(tempDir);
  }

  Future<void> cleanProject() async {
    await flutter.stop();
    tryToDelete(tempDir);
  }

  Future<void> breakInBuildMethod(FlutterTestDriver flutter) async {
    await flutter.breakAt(
      project.buildMethodBreakpointUri,
      project.buildMethodBreakpointLine,
    );
  }

  Future<void> breakInTopLevelFunction(FlutterTestDriver flutter) async {
    await flutter.breakAt(
      project.topLevelFunctionBreakpointUri,
      project.topLevelFunctionBreakpointLine,
    );
  }

  testWithoutContext('flutter run expression evaluation - can evaluate trivial expressions in top level function', () async {
    await initProject();
    await flutter.run(withDebugger: true);
    await breakInTopLevelFunction(flutter);
    await evaluateTrivialExpressions(flutter);
    await cleanProject();
  });

  testWithoutContext('flutter run expression evaluation - can evaluate trivial expressions in build method', () async {
    await initProject();
    await flutter.run(withDebugger: true);
    await breakInBuildMethod(flutter);
    await evaluateTrivialExpressions(flutter);
    await cleanProject();
  });

  testWithoutContext('flutter run expression evaluation - can evaluate complex expressions in top level function', () async {
    await initProject();
    await flutter.run(withDebugger: true);
    await breakInTopLevelFunction(flutter);
    await evaluateComplexExpressions(flutter);
    await cleanProject();
  });

  testWithoutContext('flutter run expression evaluation - can evaluate complex expressions in build method', () async {
    await initProject();
    await flutter.run(withDebugger: true);
    await breakInBuildMethod(flutter);
    await evaluateComplexExpressions(flutter);
    await cleanProject();
  });

  testWithoutContext('flutter run expression evaluation - can evaluate expressions returning complex objects in top level function', () async {
    await initProject();
    await flutter.run(withDebugger: true);
    await breakInTopLevelFunction(flutter);
    await evaluateComplexReturningExpressions(flutter);
    await cleanProject();
  });

  testWithoutContext('flutter run expression evaluation - can evaluate expressions returning complex objects in build method', () async {
    await initProject();
    await flutter.run(withDebugger: true);
    await breakInBuildMethod(flutter);
    await evaluateComplexReturningExpressions(flutter);
    await cleanProject();
  });
}

void batch2() {
  final TestsProject project = TestsProject();
  late Directory tempDir;
  late FlutterTestTestDriver flutter;

  Future<void> initProject() async {
    tempDir = createResolvedTempDirectorySync('test_expression_eval_test.');
    await project.setUpIn(tempDir);
    flutter = FlutterTestTestDriver(tempDir);
  }

  Future<void> cleanProject() async {
    await flutter.waitForCompletion();
    tryToDelete(tempDir);
  }

  testWithoutContext('flutter test expression evaluation - can evaluate trivial expressions in a test', () async {
    await initProject();
    await flutter.test(
      withDebugger: true,
      beforeStart: () => flutter.addBreakpoint(project.breakpointUri, project.breakpointLine),
    );
    await flutter.waitForPause();
    await evaluateTrivialExpressions(flutter);
    await cleanProject();
  });

  testWithoutContext('flutter test expression evaluation - can evaluate complex expressions in a test', () async {
    await initProject();
    await flutter.test(
      withDebugger: true,
      beforeStart: () => flutter.addBreakpoint(project.breakpointUri, project.breakpointLine),
    );
    await flutter.waitForPause();
    await evaluateComplexExpressions(flutter);
    await cleanProject();
  });

  testWithoutContext('flutter test expression evaluation - can evaluate expressions returning complex objects in a test', () async {
    await initProject();
    await flutter.test(
      withDebugger: true,
      beforeStart: () => flutter.addBreakpoint(project.breakpointUri, project.breakpointLine),
    );
    await flutter.waitForPause();
    await evaluateComplexReturningExpressions(flutter);
    await cleanProject();
  });
}

Future<void> evaluateTrivialExpressions(FlutterTestDriver flutter) async {
  ObjRef res;

  res = await flutter.evaluateInFrame('"test"');
  expectValueOfType(res, InstanceKind.kString, 'test');

  res = await flutter.evaluateInFrame('1');
  expectValueOfType(res, InstanceKind.kInt, 1.toString());

  res = await flutter.evaluateInFrame('true');
  expectValueOfType(res, InstanceKind.kBool, true.toString());
}

Future<void> evaluateComplexExpressions(FlutterTestDriver flutter) async {
  final ObjRef res = await flutter.evaluateInFrame('new DateTime(2000).year');
  expectValueOfType(res, InstanceKind.kInt, '2000');
}

Future<void> evaluateComplexReturningExpressions(FlutterTestDriver flutter) async {
  final DateTime date = DateTime(2000);
  final ObjRef resp = await flutter.evaluateInFrame('new DateTime(2000)');
  expectInstanceOfClass(resp, 'DateTime');
  final ObjRef res = await flutter.evaluate(resp.id!, r'"$year-$month-$day"');
  expectValue(res, '${date.year}-${date.month}-${date.day}');
}

void expectInstanceOfClass(ObjRef result, String name) {
  expect(result,
    const TypeMatcher<InstanceRef>()
      .having((InstanceRef instance) => instance.classRef!.name, 'resp.classRef.name', name));
}

void expectValueOfType(ObjRef result, String kind, String message) {
  expect(result,
    const TypeMatcher<InstanceRef>()
      .having((InstanceRef instance) => instance.kind, 'kind', kind)
      .having((InstanceRef instance) => instance.valueAsString, 'valueAsString', message));
}

void expectValue(ObjRef result, String message) {
  expect(result,
    const TypeMatcher<InstanceRef>()
      .having((InstanceRef instance) => instance.valueAsString, 'valueAsString', message));
}

void main() {
  batch1();
  batch2();
}
