// 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,
    ];
  }
}
