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

// @dart = 2.8

import 'package:file/file.dart';
import 'package:vm_service/vm_service.dart';

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

void main() {
  group('Flutter run for web', () {
    final BasicProject project = BasicProject();
    Directory tempDir;
    FlutterRunTestDriver flutter;

    setUp(() async {
      tempDir = createResolvedTempDirectorySync('run_expression_eval_test.');
      await project.setUpIn(tempDir);
      flutter = FlutterRunTestDriver(tempDir);
    });

    tearDown(() async {
      await flutter.stop();
      tryToDelete(tempDir);
    });

    Future<void> start({bool expressionEvaluation}) async {
      // The non-test project has a loop around its breakpoints.
      // No need to start paused as all breakpoint would be eventually reached.
      await flutter.run(
        withDebugger: true, chrome: true,
        expressionEvaluation: expressionEvaluation,
        additionalCommandArgs: <String>['--verbose']);
    }

    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('cannot evaluate expression if feature is disabled', () async {
      await start(expressionEvaluation: false);
      await breakInTopLevelFunction(flutter);
      await failToEvaluateExpression(flutter);
    });

    testWithoutContext('shows no native javascript objects in static scope', () async {
      await start(expressionEvaluation: true);
      await breakInTopLevelFunction(flutter);
      await checkStaticScope(flutter);
    });

    testWithoutContext('can handle compilation errors', () async {
      await start(expressionEvaluation: true);
      await breakInTopLevelFunction(flutter);
      await evaluateErrorExpressions(flutter);
    });

    testWithoutContext('can evaluate trivial expressions in top level function', () async {
      await start(expressionEvaluation: true);
      await breakInTopLevelFunction(flutter);
      await evaluateTrivialExpressions(flutter);
    });

    testWithoutContext('can evaluate trivial expressions in build method', () async {
      await start(expressionEvaluation: true);
      await breakInBuildMethod(flutter);
      await evaluateTrivialExpressions(flutter);
    });

    testWithoutContext('can evaluate complex expressions in top level function', () async {
      await start(expressionEvaluation: true);
      await breakInTopLevelFunction(flutter);
      await evaluateComplexExpressions(flutter);
    });

    testWithoutContext('can evaluate complex expressions in build method', () async {
      await start(expressionEvaluation: true);
      await breakInBuildMethod(flutter);
      await evaluateComplexExpressions(flutter);
    });

    testWithoutContext('can evaluate trivial expressions in library without pause', () async {
      await start(expressionEvaluation: true);
      await evaluateTrivialExpressionsInLibrary(flutter);
    });

    testWithoutContext('can evaluate complex expressions in library without pause', () async {
      await start(expressionEvaluation: true);
      await evaluateComplexExpressionsInLibrary(flutter);
    });
  });


  group('Flutter test for web', () {
    final TestsProject project = TestsProject();
    Directory tempDir;
    FlutterRunTestDriver flutter;

    setUp(() async {
      tempDir = createResolvedTempDirectorySync('run_expression_eval_test.');
      await project.setUpIn(tempDir);
      flutter = FlutterRunTestDriver(tempDir);
    });

    tearDown(() async {
      await flutter.stop();
      tryToDelete(tempDir);
    });

    Future<Isolate> breakInMethod(FlutterTestDriver flutter) async {
      await flutter.addBreakpoint(
        project.breakpointAppUri,
        project.breakpointLine,
      );
      await flutter.resume();
      return 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,
        additionalCommandArgs: <String>['--verbose']);
    }

    testWithoutContext('cannot evaluate expressions if feature is disabled', () async {
      await startPaused(expressionEvaluation: false);
      await breakInMethod(flutter);
      await failToEvaluateExpression(flutter);
    });

    testWithoutContext('can evaluate trivial expressions in a test', () async {
      await startPaused(expressionEvaluation: true);
      await breakInMethod(flutter);
      await evaluateTrivialExpressions(flutter);
    });

    testWithoutContext('can evaluate complex expressions in a test', () async {
      await startPaused(expressionEvaluation: true);
      await breakInMethod(flutter);
      await evaluateComplexExpressions(flutter);
    });

    testWithoutContext('can evaluate trivial expressions in library without pause', () async {
      await startPaused(expressionEvaluation: true);
      await evaluateTrivialExpressionsInLibrary(flutter);
    });

    testWithoutContext('can evaluate complex expressions in library without pause', () async {
      await startPaused(expressionEvaluation: true);
      await evaluateComplexExpressionsInLibrary(flutter);
    });
  });
}

Future<void> failToEvaluateExpression(FlutterTestDriver flutter) async {
  ObjRef res;
  try {
    res = await flutter.evaluateInFrame('"test"');
  } on RPCError catch (e) {
    expect(e.message, contains('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());
}

Future<void> evaluateTrivialExpressionsInLibrary(FlutterTestDriver flutter) async {
  final LibraryRef library = await getRootLibrary(flutter);
  final ObjRef res = await flutter.evaluate(library.id, '"test"');
  expectInstance(res, InstanceKind.kString, 'test');
}

Future<void> evaluateComplexExpressionsInLibrary(FlutterTestDriver flutter) async {
  final LibraryRef library = await getRootLibrary(flutter);
  final ObjRef res = await flutter.evaluate(library.id, 'new DateTime.now().year');
  expectInstance(res, InstanceKind.kDouble, DateTime.now().year.toString());
}

Future<LibraryRef> getRootLibrary(FlutterTestDriver flutter) async {
  // `isolate.rootLib` returns incorrect library, so find the
  // entrypoint manually here instead.
  //
  // Issue: https://github.com/dart-lang/sdk/issues/44760
  final Isolate isolate = await flutter.getFlutterIsolate();
  return isolate.libraries
    .firstWhere((LibraryRef l) => l.uri.contains('org-dartlang-app'));
}

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