// 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 'dart:async';
import 'dart:io';

import 'package:file/file.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:matcher/matcher.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();
  Directory tempDir;
  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,
    );
  }

  test('flutter run expression evaluation - can handle compilation errors', () async {
    await initProject();
    await _flutter.run(withDebugger: true, chrome: true);
    await breakInTopLevelFunction(_flutter);
    await evaluateErrorExpressions(_flutter);
    await cleanProject();
  }, skip: 'CI not setup for web tests'); // https://github.com/flutter/flutter/issues/53779

  test('flutter run expression evaluation - can evaluate trivial expressions in top level function', () async {
    await initProject();
    await _flutter.run(withDebugger: true, chrome: true);
    await breakInTopLevelFunction(_flutter);
    await evaluateTrivialExpressions(_flutter);
    await cleanProject();
  }, skip: 'CI not setup for web tests'); // https://github.com/flutter/flutter/issues/53779

  test('flutter run expression evaluation - can evaluate trivial expressions in build method', () async {
    await initProject();
    await _flutter.run(withDebugger: true, chrome: true);
    await breakInBuildMethod(_flutter);
    await evaluateTrivialExpressions(_flutter);
    await cleanProject();
  }, skip: 'CI not setup for web tests'); // https://github.com/flutter/flutter/issues/53779

  test('flutter run expression evaluation - can evaluate complex expressions in top level function', () async {
    await initProject();
    await _flutter.run(withDebugger: true, chrome: true);
    await breakInTopLevelFunction(_flutter);
    await evaluateComplexExpressions(_flutter);
    await cleanProject();
  }, skip: 'CI not setup for web tests'); // https://github.com/flutter/flutter/issues/53779

  test('flutter run expression evaluation - can evaluate complex expressions in build method', () async {
    await initProject();
    await _flutter.run(withDebugger: true, chrome: true);
    await breakInBuildMethod(_flutter);
    await evaluateComplexExpressions(_flutter);
    await cleanProject();
  }, skip: 'CI not setup for web tests'); // https://github.com/flutter/flutter/issues/53779
}

void batch2() {
  final TestsProject _project = TestsProject();
  Directory tempDir;
  FlutterRunTestDriver _flutter;

  Future<void> initProject() async {
    tempDir = createResolvedTempDirectorySync('test_expression_eval_test.');
    await _project.setUpIn(tempDir);
    _flutter = FlutterRunTestDriver(tempDir);
  }

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

  Future<void> breakInMethod(FlutterTestDriver flutter) async {
    await _flutter.breakAt(
      _project.breakpointAppUri,
      _project.breakpointLine,
    );
  }

  test('flutter test expression evaluation - can evaluate trivial expressions in a test', () async {
    await initProject();
    await _flutter.run(withDebugger: true, chrome: true, script: _project.testFilePath);
    await breakInMethod(_flutter);
    await evaluateTrivialExpressions(_flutter);
    await cleanProject();
  }, skip: 'CI not setup for web tests'); // https://github.com/flutter/flutter/issues/53779

  test('flutter test expression evaluation - can evaluate complex expressions in a test', () async {
    await initProject();
    await _flutter.run(withDebugger: true, chrome: true, script: _project.testFilePath);
    await breakInMethod(_flutter);
    await evaluateComplexExpressions(_flutter);
    await cleanProject();
  }, skip: 'CI not setup for web tests'); // https://github.com/flutter/flutter/issues/53779
}


Future<void> evaluateErrorExpressions(FlutterTestDriver flutter) async {
  final ObjRef res = await flutter.evaluateInFrame('typo');
  expectError(res, 'CompilationError: Getter not found: \'typo\'.\ntypo\n^^^^');
}

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

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

  res = await flutter.evaluateInFrame('1');
  expectInstance(res, InstanceKind.kDouble, 1.toString());

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

Future<void> evaluateComplexExpressions(FlutterTestDriver flutter) async {
  final ObjRef res = await flutter.evaluateInFrame('new DateTime.now().year');
  expectInstance(res, InstanceKind.kDouble, DateTime.now().year.toString());
}

void expectInstance(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 expectError(ObjRef result, String message) {
  expect(result,
    const TypeMatcher<ErrorRef>()
      .having((ErrorRef instance) => instance.message, 'message', message));
}

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