// 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> start({bool expressionEvaluation}) {
    // The non-test project has a loop around its breakpoints.
    // No need to start paused as all breakpoint would be eventually reached.
    return  _flutter.run(
      withDebugger: true, chrome: true,
      expressionEvaluation: expressionEvaluation);
  }

  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 - error if expression evaluation disabled', () async {
    await initProject();
    await start(expressionEvaluation: false);
    await breakInTopLevelFunction(_flutter);
    await failToEvaluateExpression(_flutter);
    await cleanProject();
  }, skip: 'CI not setup for web tests'); // https://github.com/flutter/flutter/issues/53779

 test('flutter run expression evaluation - no native javascript objects in static scope', () async {
    await initProject();
    await start(expressionEvaluation: true);
    await breakInTopLevelFunction(_flutter);
    await checkStaticScope(_flutter);
    await cleanProject();
  }, skip: 'CI not setup for web tests'); // https://github.com/flutter/flutter/issues/53779

  test('flutter run expression evaluation - can handle compilation errors', () async {
    await initProject();
    await start(expressionEvaluation: 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 start(expressionEvaluation: 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 start(expressionEvaluation: 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 start(expressionEvaluation: 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.addBreakpoint(
      _project.breakpointAppUri,
      _project.breakpointLine,
    );
    await _flutter.resume();
    await _flutter.waitForPause();
  }

  Future<void> startPaused({bool expressionEvaluation}) {
    // The test project does not have a loop around its breakpoints.
    // Start paused so we can set a breakpoint before passing it
    // in the execution.
    return  _flutter.run(
      withDebugger: true, chrome: true,
      expressionEvaluation: expressionEvaluation,
      startPaused: true, script: _project.testFilePath);
  }

  test('flutter test expression evaluation - error if expression evaluation disabled', () async {
    await initProject();
    await startPaused(expressionEvaluation: false);
    await breakInMethod(_flutter);
    await failToEvaluateExpression(_flutter);
    await cleanProject();
  }, skip: 'CI not setup for web tests'); // https://github.com/flutter/flutter/issues/53779

  test('flutter test expression evaluation - can evaluate trivial expressions in a test', () async {
    await initProject();
    await startPaused(expressionEvaluation: true);
    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 startPaused(expressionEvaluation: true);
    await breakInMethod(_flutter);
    await evaluateComplexExpressions(_flutter);
    await cleanProject();
  }, skip: 'CI not setup for web tests'); // https://github.com/flutter/flutter/issues/53779
}

Future<void> failToEvaluateExpression(FlutterTestDriver flutter) async {
  ObjRef res;
  try {
    res = await flutter.evaluateInFrame('"test"');
  } on RPCError catch (e) {
    expect(e.message, contains(
      'UnimplementedError: '
      'Expression evaluation is not supported for this configuration'));
  }
  expect(res, null);
}

Future<void> checkStaticScope(FlutterTestDriver flutter) async {
  final Frame res = await flutter.getTopStackFrame();
  expect(res.vars, equals(<BoundVariable>[]));
}

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();
}
