// 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 '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 AndroidManifest.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,
  );
}

// Unfortunately Device, despite not being immutable, has an `operator ==`.
// Until we fix that, we have to also ignore related lints here.
// ignore: avoid_implementing_value_types
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,
    ];
  }
}
