// Copyright 2015 The Chromium 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 'package:flutter_tools/src/android/android_workflow.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/commands/daemon.dart';
import 'package:flutter_tools/src/globals.dart';
import 'package:flutter_tools/src/ios/ios_workflow.dart';
import 'package:flutter_tools/src/resident_runner.dart';
import 'package:test/test.dart';

import '../src/context.dart';
import '../src/mocks.dart';

void main() {
  Daemon daemon;
  NotifyingLogger notifyingLogger;

  group('daemon', () {
    setUp(() {
      notifyingLogger = new NotifyingLogger();
    });

    tearDown(() {
      if (daemon != null)
        return daemon.shutdown();
      notifyingLogger.dispose();
    });

    testUsingContext('daemon.version command should succeed', () async {
      final StreamController<Map<String, dynamic>> commands = new StreamController<Map<String, dynamic>>();
      final StreamController<Map<String, dynamic>> responses = new StreamController<Map<String, dynamic>>();
      daemon = new Daemon(
        commands.stream,
        responses.add,
        notifyingLogger: notifyingLogger
      );
      commands.add(<String, dynamic>{'id': 0, 'method': 'daemon.version'});
      final Map<String, dynamic> response = await responses.stream.firstWhere(_notEvent);
      expect(response['id'], 0);
      expect(response['result'], isNotEmpty);
      expect(response['result'] is String, true);
      responses.close();
      commands.close();
    });

    testUsingContext('printError should send daemon.logMessage event', () async {
      final StreamController<Map<String, dynamic>> commands = new StreamController<Map<String, dynamic>>();
      final StreamController<Map<String, dynamic>> responses = new StreamController<Map<String, dynamic>>();
      daemon = new Daemon(
        commands.stream,
        responses.add,
        notifyingLogger: notifyingLogger,
      );
      printError('daemon.logMessage test');
      final Map<String, dynamic> response = await responses.stream.firstWhere((Map<String, dynamic> map) {
        return map['event'] == 'daemon.logMessage' && map['params']['level'] == 'error';
      });
      expect(response['id'], isNull);
      expect(response['event'], 'daemon.logMessage');
      final Map<String, String> logMessage = response['params'];
      expect(logMessage['level'], 'error');
      expect(logMessage['message'], 'daemon.logMessage test');
      responses.close();
      commands.close();
    }, overrides: <Type, Generator>{
      Logger: () => notifyingLogger,
    });

    testUsingContext('printStatus should log to stdout when logToStdout is enabled', () async {
      final StringBuffer buffer = new StringBuffer();

      await runZoned(() async {
        final StreamController<Map<String, dynamic>> commands = new StreamController<Map<String, dynamic>>();
        final StreamController<Map<String, dynamic>> responses = new StreamController<Map<String, dynamic>>();
        daemon = new Daemon(
          commands.stream,
          responses.add,
          notifyingLogger: notifyingLogger,
          logToStdout: true,
        );
        printStatus('daemon.logMessage test');
        // Service the event loop.
        await new Future<Null>.value();
      }, zoneSpecification: new ZoneSpecification(print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
        buffer.writeln(line);
      }));

      expect(buffer.toString().trim(), 'daemon.logMessage test');
    }, overrides: <Type, Generator>{
      Logger: () => notifyingLogger,
    });

    testUsingContext('daemon.shutdown command should stop daemon', () async {
      final StreamController<Map<String, dynamic>> commands = new StreamController<Map<String, dynamic>>();
      final StreamController<Map<String, dynamic>> responses = new StreamController<Map<String, dynamic>>();
      daemon = new Daemon(
        commands.stream,
        responses.add,
        notifyingLogger: notifyingLogger
      );
      commands.add(<String, dynamic>{'id': 0, 'method': 'daemon.shutdown'});
      return daemon.onExit.then<Null>((int code) {
        responses.close();
        commands.close();
        expect(code, 0);
      });
    });

    testUsingContext('app.start without a deviceId should report an error', () async {
      final DaemonCommand command = new DaemonCommand();
      applyMocksToCommand(command);

      final StreamController<Map<String, dynamic>> commands = new StreamController<Map<String, dynamic>>();
      final StreamController<Map<String, dynamic>> responses = new StreamController<Map<String, dynamic>>();
      daemon = new Daemon(
        commands.stream,
        responses.add,
        daemonCommand: command,
        notifyingLogger: notifyingLogger
      );

      commands.add(<String, dynamic>{ 'id': 0, 'method': 'app.start' });
      final Map<String, dynamic> response = await responses.stream.firstWhere(_notEvent);
      expect(response['id'], 0);
      expect(response['error'], contains('deviceId is required'));
      responses.close();
      commands.close();
    });

    testUsingContext('app.restart without an appId should report an error', () async {
      final DaemonCommand command = new DaemonCommand();
      applyMocksToCommand(command);

      final StreamController<Map<String, dynamic>> commands = new StreamController<Map<String, dynamic>>();
      final StreamController<Map<String, dynamic>> responses = new StreamController<Map<String, dynamic>>();
      daemon = new Daemon(
        commands.stream,
        responses.add,
        daemonCommand: command,
        notifyingLogger: notifyingLogger
      );

      commands.add(<String, dynamic>{ 'id': 0, 'method': 'app.restart' });
      final Map<String, dynamic> response = await responses.stream.firstWhere(_notEvent);
      expect(response['id'], 0);
      expect(response['error'], contains('appId is required'));
      responses.close();
      commands.close();
    });

    testUsingContext('ext.flutter.debugPaint via service extension without an appId should report an error', () async {
      final DaemonCommand command = new DaemonCommand();
      applyMocksToCommand(command);

      final StreamController<Map<String, dynamic>> commands = new StreamController<Map<String, dynamic>>();
      final StreamController<Map<String, dynamic>> responses = new StreamController<Map<String, dynamic>>();
      daemon = new Daemon(
          commands.stream,
          responses.add,
          daemonCommand: command,
          notifyingLogger: notifyingLogger
      );

      commands.add(<String, dynamic>{
        'id': 0,
        'method': 'app.callServiceExtension',
        'params': <String, String> {
          'methodName': 'ext.flutter.debugPaint'
        }
      });
      final Map<String, dynamic> response = await responses.stream.firstWhere(_notEvent);
      expect(response['id'], 0);
      expect(response['error'], contains('appId is required'));
      responses.close();
      commands.close();
    });

    testUsingContext('app.stop without appId should report an error', () async {
      final DaemonCommand command = new DaemonCommand();
      applyMocksToCommand(command);

      final StreamController<Map<String, dynamic>> commands = new StreamController<Map<String, dynamic>>();
      final StreamController<Map<String, dynamic>> responses = new StreamController<Map<String, dynamic>>();
      daemon = new Daemon(
        commands.stream,
        responses.add,
        daemonCommand: command,
        notifyingLogger: notifyingLogger
      );

      commands.add(<String, dynamic>{ 'id': 0, 'method': 'app.stop' });
      final Map<String, dynamic> response = await responses.stream.firstWhere(_notEvent);
      expect(response['id'], 0);
      expect(response['error'], contains('appId is required'));
      responses.close();
      commands.close();
    });

    testUsingContext('daemon should send showMessage on startup if no Android devices are available', () async {
      final StreamController<Map<String, dynamic>> commands = new StreamController<Map<String, dynamic>>();
      final StreamController<Map<String, dynamic>> responses = new StreamController<Map<String, dynamic>>();
      daemon = new Daemon(
          commands.stream,
          responses.add,
          notifyingLogger: notifyingLogger,
      );

      final Map<String, dynamic> response = await responses.stream.first;
      expect(response['event'], 'daemon.showMessage');
      expect(response['params'], isMap);
      expect(response['params'], containsPair('level', 'warning'));
      expect(response['params'], containsPair('title', 'Unable to list devices'));
      expect(response['params'], containsPair('message', contains('Unable to discover Android devices')));
    }, overrides: <Type, Generator>{
      AndroidWorkflow: () => new MockAndroidWorkflow(canListDevices: false),
      IOSWorkflow: () => new MockIOSWorkflow(),
    });

    testUsingContext('device.getDevices should respond with list', () async {
      final StreamController<Map<String, dynamic>> commands = new StreamController<Map<String, dynamic>>();
      final StreamController<Map<String, dynamic>> responses = new StreamController<Map<String, dynamic>>();
      daemon = new Daemon(
        commands.stream,
        responses.add,
        notifyingLogger: notifyingLogger
      );
      commands.add(<String, dynamic>{'id': 0, 'method': 'device.getDevices'});
      final Map<String, dynamic> response = await responses.stream.firstWhere(_notEvent);
      expect(response['id'], 0);
      expect(response['result'], isList);
      responses.close();
      commands.close();
    });

    testUsingContext('should send device.added event when device is discovered', () {
      final StreamController<Map<String, dynamic>> commands = new StreamController<Map<String, dynamic>>();
      final StreamController<Map<String, dynamic>> responses = new StreamController<Map<String, dynamic>>();
      daemon = new Daemon(
          commands.stream,
          responses.add,
          notifyingLogger: notifyingLogger
      );

      final MockPollingDeviceDiscovery discoverer = new MockPollingDeviceDiscovery();
      daemon.deviceDomain.addDeviceDiscoverer(discoverer);
      discoverer.addDevice(new MockAndroidDevice());

      return responses.stream.first.then((Map<String, dynamic> response) {
        expect(response['event'], 'device.added');
        expect(response['params'], isMap);

        final Map<String, dynamic> params = response['params'];
        expect(params['platform'], isNotEmpty); // the mock device has a platform of 'android-arm'

        responses.close();
        commands.close();
      });
    }, overrides: <Type, Generator>{
      AndroidWorkflow: () => new MockAndroidWorkflow(),
      IOSWorkflow: () => new MockIOSWorkflow(),
    });
  });

  group('daemon serialization', () {
    test('OperationResult', () {
      expect(
        jsonEncodeObject(OperationResult.ok),
        '{"code":0,"message":""}'
      );
      expect(
        jsonEncodeObject(new OperationResult(1, 'foo')),
        '{"code":1,"message":"foo"}'
      );
      expect(
        jsonEncodeObject(new OperationResult(0, 'foo', hintMessage: 'my hint', hintId: 'myId')),
        '{"code":0,"message":"foo","hintMessage":"my hint","hintId":"myId"}'
      );
    });
  });
}

bool _notEvent(Map<String, dynamic> map) => map['event'] == null;

class MockAndroidWorkflow extends AndroidWorkflow {
  MockAndroidWorkflow({ this.canListDevices: true });

  @override
  final bool canListDevices;
}

class MockIOSWorkflow extends IOSWorkflow {
  MockIOSWorkflow({ this.canListDevices:true });

  @override
  final bool canListDevices;
}
