// 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:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/base/io.dart' as io;
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/test/integration_test_device.dart';
import 'package:flutter_tools/src/test/test_device.dart';
import 'package:flutter_tools/src/vmservice.dart';
import 'package:stream_channel/stream_channel.dart';
import 'package:test/fake.dart';
import 'package:vm_service/vm_service.dart' as vm_service;

import '../src/context.dart';
import '../src/fake_devices.dart';
import '../src/fake_vm_services.dart';

final vm_service.Isolate isolate = vm_service.Isolate(
  id: '1',
  pauseEvent: vm_service.Event(
      kind: vm_service.EventKind.kResume,
      timestamp: 0
  ),
  breakpoints: <vm_service.Breakpoint>[],
  libraries: <vm_service.LibraryRef>[
    vm_service.LibraryRef(
      id: '1',
      uri: 'file:///hello_world/main.dart',
      name: '',
    ),
  ],
  livePorts: 0,
  name: 'test',
  number: '1',
  pauseOnExit: false,
  runnable: true,
  startTime: 0,
  isSystemIsolate: false,
  isolateFlags: <vm_service.IsolateFlag>[],
  extensionRPCs: <String>[kIntegrationTestMethod],
);

final FlutterView fakeFlutterView = FlutterView(
  id: 'a',
  uiIsolate: isolate,
);

final FakeVmServiceRequest listViewsRequest = FakeVmServiceRequest(
  method: kListViewsMethod,
  jsonResponse: <String, Object>{
    'views': <Object>[
      fakeFlutterView.toJson(),
    ],
  },
);

final Uri observatoryUri = Uri.parse('http://localhost:1234');

void main() {
  late FakeVmServiceHost fakeVmServiceHost;
  late TestDevice testDevice;

  setUp(() {
    testDevice = IntegrationTestTestDevice(
      id: 1,
      device: FakeDevice(
        'ephemeral',
        'ephemeral',
        type: PlatformType.android,
        launchResult: LaunchResult.succeeded(observatoryUri: observatoryUri),
      ),
      debuggingOptions: DebuggingOptions.enabled(
        BuildInfo.debug,
      ),
      userIdentifier: '',
    );

    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
      const FakeVmServiceRequest(
        method: 'streamListen',
        args: <String, Object>{
          'streamId': 'Isolate',
        },
      ),
      listViewsRequest,
      FakeVmServiceRequest(
        method: 'getIsolate',
        jsonResponse: isolate.toJson(),
        args: <String, Object>{
          'isolateId': '1',
        },
      ),
      const FakeVmServiceRequest(
        method: 'streamCancel',
        args: <String, Object>{
          'streamId': 'Isolate',
        },
      ),
      const FakeVmServiceRequest(
        method: 'streamListen',
        args: <String, Object>{
          'streamId': 'Extension',
        },
      ),
    ]);
  });

  testUsingContext('will not start when package missing', () async {
    await expectLater(
      testDevice.start('entrypointPath'),
      throwsA(
        isA<TestDeviceException>().having(
          (Exception e) => e.toString(),
          'description',
          contains('No application found for TargetPlatform.android_arm'),
        ),
      ),
    );
  });

  testUsingContext('Can start the entrypoint', () async {
    await testDevice.start('entrypointPath');

    expect(await testDevice.observatoryUri, observatoryUri);
    expect(testDevice.finished, doesNotComplete);
  }, overrides: <Type, Generator>{
    ApplicationPackageFactory: () => FakeApplicationPackageFactory(),
    VMServiceConnector: () => (Uri httpUri, {
      ReloadSources? reloadSources,
      Restart? restart,
      CompileExpression? compileExpression,
      GetSkSLMethod? getSkSLMethod,
      PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
      io.CompressionOptions? compression,
      Device? device,
      Logger? logger,
    }) async => fakeVmServiceHost.vmService,
  });

  testUsingContext('Can kill the started device', () async {
    await testDevice.start('entrypointPath');
    await testDevice.kill();

    expect(testDevice.finished, completes);
  }, overrides: <Type, Generator>{
    ApplicationPackageFactory: () => FakeApplicationPackageFactory(),
    VMServiceConnector: () => (Uri httpUri, {
      ReloadSources? reloadSources,
      Restart? restart,
      CompileExpression? compileExpression,
      GetSkSLMethod? getSkSLMethod,
      PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
      io.CompressionOptions? compression,
      Device? device,
      Logger? logger,
    }) async => fakeVmServiceHost.vmService,
  });

  testUsingContext('when the device starts without providing an observatory URI', () async {
    final TestDevice testDevice = IntegrationTestTestDevice(
      id: 1,
      device: FakeDevice(
        'ephemeral',
        'ephemeral',
        type: PlatformType.android,
        launchResult: LaunchResult.succeeded(),
      ),
      debuggingOptions: DebuggingOptions.enabled(
        BuildInfo.debug,
      ),
      userIdentifier: '',
    );

    expect(() => testDevice.start('entrypointPath'), throwsA(isA<TestDeviceException>()));
  }, overrides: <Type, Generator>{
    VMServiceConnector: () => (Uri httpUri, {
      ReloadSources? reloadSources,
      Restart? restart,
      CompileExpression? compileExpression,
      GetSkSLMethod? getSkSLMethod,
      PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
      io.CompressionOptions? compression,
      Device? device,
    }) async => fakeVmServiceHost.vmService,
  });

  testUsingContext('when the device fails to start', () async {
    final TestDevice testDevice = IntegrationTestTestDevice(
      id: 1,
      device: FakeDevice(
        'ephemeral',
        'ephemeral',
        type: PlatformType.android,
        launchResult: LaunchResult.failed(),
      ),
      debuggingOptions: DebuggingOptions.enabled(
        BuildInfo.debug,
      ),
      userIdentifier: '',
    );

    expect(() => testDevice.start('entrypointPath'), throwsA(isA<TestDeviceException>()));
  }, overrides: <Type, Generator>{
    VMServiceConnector: () => (Uri httpUri, {
      ReloadSources? reloadSources,
      Restart? restart,
      CompileExpression? compileExpression,
      GetSkSLMethod? getSkSLMethod,
      PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
      io.CompressionOptions? compression,
      Device? device,
    }) async => fakeVmServiceHost.vmService,
  });

  testUsingContext('Can handle closing of the VM service', () async {
    final StreamChannel<String> channel = await testDevice.start('entrypointPath');
    await fakeVmServiceHost.vmService.dispose();
    expect(await channel.stream.isEmpty, true);
  }, overrides: <Type, Generator>{
    ApplicationPackageFactory: () => FakeApplicationPackageFactory(),
    VMServiceConnector: () => (Uri httpUri, {
      ReloadSources? reloadSources,
      Restart? restart,
      CompileExpression? compileExpression,
      GetSkSLMethod? getSkSLMethod,
      PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
      io.CompressionOptions? compression,
      Device? device,
      Logger? logger,
    }) async => fakeVmServiceHost.vmService,
  });
}

class FakeApplicationPackageFactory extends Fake implements ApplicationPackageFactory {
  @override
  Future<ApplicationPackage> getPackageForPlatform(
    TargetPlatform platform, {
    BuildInfo? buildInfo,
    File? applicationBinary,
  }) async => FakeApplicationPackage();
}

class FakeApplicationPackage extends Fake implements ApplicationPackage { }
