// 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', '--web-renderer=html']);
    }

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

    testWithoutContext('evaluated expression includes web library environment defines', () async {
      await start(expressionEvaluation: true);
      await evaluateWebLibraryBooleanFromEnvironmentInLibrary(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,
      );
      return flutter.resume(waitForNextPause: true);
    }

    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', '--web-renderer=html']);
    }

    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);
    });
    testWithoutContext('evaluated expression includes web library environment defines', () async {
      await startPaused(expressionEvaluation: true);
      await evaluateWebLibraryBooleanFromEnvironmentInLibrary(flutter);
    });
  });
}

Future<void> failToEvaluateExpression(FlutterTestDriver flutter) async {
  await expectLater(
    flutter.evaluateInFrame('"test"'),
    throwsA(isA<RPCError>().having(
      (RPCError error) => error.message,
      'message',
      contains('Expression evaluation is not supported for this configuration'),
    )),
  );
}

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

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<void> evaluateWebLibraryBooleanFromEnvironmentInLibrary(FlutterTestDriver flutter) async {
  final LibraryRef library = await getRootLibrary(flutter);
  final ObjRef res = await flutter.evaluate(library.id, 'const bool.fromEnvironment("dart.library.html")');
  expectInstance(res, InstanceKind.kBool, true.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', contains(message)));
}
