// 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 'dart:async';

import 'package:flutter_tools/src/android/android_device.dart';
import 'package:test/fake.dart';

import '../../src/common.dart';
import '../../src/fake_process_manager.dart';

const int kLollipopVersionCode = 21;
const String kLastLogcatTimestamp = '11-27 15:39:04.506';

/// By default the android log reader accepts lines that match no patterns
/// if the previous line was a match. Include an intentionally non-matching
/// line as the first input to disable this behavior.
const String kDummyLine = 'Contents are not important\n';

void main() {
  testWithoutContext('AdbLogReader calls adb logcat with expected flags apiVersion 21', () async {
    final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      const FakeCommand(
        command: <String>[
          'adb',
          '-s',
          '1234',
          'shell',
          '-x',
          'logcat',
          '-v',
          'time',
          '-T',
          '\'$kLastLogcatTimestamp\'',
        ],
      )
    ]);
    await AdbLogReader.createLogReader(
      createFakeDevice(kLollipopVersionCode),
      processManager,
    );

    expect(processManager, hasNoRemainingExpectations);
  });

  testWithoutContext('AdbLogReader calls adb logcat with expected flags apiVersion < 21', () async {
    final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      const FakeCommand(
        command: <String>[
          'adb',
          '-s',
          '1234',
          'shell',
          '-x',
          'logcat',
          '-v',
          'time',
        ],
      )
    ]);
    await AdbLogReader.createLogReader(
      createFakeDevice(kLollipopVersionCode - 1),
      processManager,
    );

    expect(processManager, hasNoRemainingExpectations);
  });

  testWithoutContext('AdbLogReader calls adb logcat with expected flags null apiVersion', () async {
    final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      const FakeCommand(
        command: <String>[
          'adb',
          '-s',
          '1234',
          'shell',
          '-x',
          'logcat',
          '-v',
          'time',
        ],
      )
    ]);
    await AdbLogReader.createLogReader(
      createFakeDevice(null),
      processManager,
    );

    expect(processManager, hasNoRemainingExpectations);
  });

  testWithoutContext('AdbLogReader calls adb logcat with expected flags when requesting past logs', () async {
    final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      const FakeCommand(
        command: <String>[
          'adb',
          '-s',
          '1234',
          'shell',
          '-x',
          'logcat',
          '-v',
          'time',
          '-s',
          'flutter',
        ],
      )
    ]);
    await AdbLogReader.createLogReader(
      createFakeDevice(null),
      processManager,
      includePastLogs: true,
    );

    expect(processManager, hasNoRemainingExpectations);
  });

  testWithoutContext('AdbLogReader handles process early exit', () async {
    final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      FakeCommand(
        command: const <String>[
          'adb',
          '-s',
          '1234',
          'shell',
          '-x',
          'logcat',
          '-v',
          'time',
        ],
        completer: Completer<void>.sync(),
        stdout: 'Hello There\n',
      )
    ]);
    final AdbLogReader logReader = await AdbLogReader.createLogReader(
      createFakeDevice(null),
      processManager,
    );
    final Completer<void> onDone = Completer<void>.sync();
    logReader.logLines.listen((String _) { }, onDone: onDone.complete);

    logReader.dispose();
    await onDone.future;
  });

  testWithoutContext('AdbLogReader does not filter output from AndroidRuntime crashes', () async {
    final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      FakeCommand(
        command: const <String>[
          'adb',
          '-s',
          '1234',
          'shell',
          '-x',
          'logcat',
          '-v',
          'time',
        ],
        completer: Completer<void>.sync(),
        // Example stack trace from an incorrectly named application:name in the AndroidManfiest.xml
        stdout:
          kDummyLine +
          '05-11 12:54:46.665 E/AndroidRuntime(11787): FATAL EXCEPTION: main\n'
          '05-11 12:54:46.665 E/AndroidRuntime(11787): Process: com.example.foobar, PID: 11787\n'
          '05-11 12:54:46.665 java.lang.RuntimeException: Unable to instantiate application '
          'io.flutter.app.FlutterApplication2: java.lang.ClassNotFoundException:\n',
      )
    ]);
    final AdbLogReader logReader = await AdbLogReader.createLogReader(
      createFakeDevice(null),
      processManager,
    );
    await expectLater(logReader.logLines, emitsInOrder(<String>[
      'E/AndroidRuntime(11787): FATAL EXCEPTION: main',
      'E/AndroidRuntime(11787): Process: com.example.foobar, PID: 11787',
      'java.lang.RuntimeException: Unable to instantiate application io.flutter.app.FlutterApplication2: java.lang.ClassNotFoundException:',
    ]));

    logReader.dispose();
  });
}

AndroidDevice createFakeDevice(int sdkLevel) {
  return FakeAndroidDevice(
    sdkLevel.toString(),
    kLastLogcatTimestamp,
  );
}

class FakeAndroidDevice extends Fake implements AndroidDevice {
  FakeAndroidDevice(this._apiVersion, this._lastLogcatTimestamp);

  final String _lastLogcatTimestamp;
  final String _apiVersion;

  @override
  String get name => 'test-device';

  @override
  Future<String> get apiVersion => Future<String>.value(_apiVersion);

  @override
  Future<String> lastLogcatTimestamp() async => _lastLogcatTimestamp;

  @override
  List<String> adbCommandForDevice(List<String> command) {
    return <String>[
      'adb', '-s', '1234', ...command,
    ];
  }
}
