// 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:args/command_runner.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/config.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/time.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/build.dart';
import 'package:flutter_tools/src/commands/config.dart';
import 'package:flutter_tools/src/commands/doctor.dart';
import 'package:flutter_tools/src/doctor.dart';
import 'package:flutter_tools/src/features.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:flutter_tools/src/runner/flutter_command.dart';
import 'package:flutter_tools/src/version.dart';
import 'package:mockito/mockito.dart';
import 'package:platform/platform.dart';
import 'package:usage/usage_io.dart';

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

void main() {
  setUpAll(() {
    Cache.disableLocking();
  });

  group('analytics', () {
    Directory tempDir;
    MockFlutterConfig mockFlutterConfig;

    setUp(() {
      Cache.flutterRoot = '../..';
      tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_tools_analytics_test.');
      mockFlutterConfig = MockFlutterConfig();
    });

    tearDown(() {
      tryToDelete(tempDir);
    });

    // Ensure we don't send anything when analytics is disabled.
    testUsingContext("doesn't send when disabled", () async {
      int count = 0;
      globals.flutterUsage.onSend.listen((Map<String, dynamic> data) => count++);

      globals.flutterUsage.enabled = false;
      await createProject(tempDir);
      expect(count, 0);

      globals.flutterUsage.enabled = true;
      await createProject(tempDir);
      expect(count, globals.flutterUsage.isFirstRun ? 0 : 4);

      count = 0;
      globals.flutterUsage.enabled = false;
      final DoctorCommand doctorCommand = DoctorCommand();
      final CommandRunner<void>runner = createTestCommandRunner(doctorCommand);
      await runner.run(<String>['doctor']);

      expect(count, 0);
    }, overrides: <Type, Generator>{
      FlutterVersion: () => FlutterVersion(const SystemClock()),
      Usage: () => Usage(
        configDirOverride: tempDir.path,
        logFile: tempDir.childFile('analytics.log').path,
        runningOnBot: true,
      ),
    });

    // Ensure we don't send for the 'flutter config' command.
    testUsingContext("config doesn't send", () async {
      int count = 0;
      globals.flutterUsage.onSend.listen((Map<String, dynamic> data) => count++);

      globals.flutterUsage.enabled = false;
      final ConfigCommand command = ConfigCommand();
      final CommandRunner<void> runner = createTestCommandRunner(command);
      await runner.run(<String>['config']);
      expect(count, 0);

      globals.flutterUsage.enabled = true;
      await runner.run(<String>['config']);

      expect(count, 0);
    }, overrides: <Type, Generator>{
      FlutterVersion: () => FlutterVersion(const SystemClock()),
      Usage: () => Usage(
        configDirOverride: tempDir.path,
        logFile: tempDir.childFile('analytics.log').path,
        runningOnBot: true,
      ),
    });

    testUsingContext('Usage records one feature in experiment setting', () async {
      when<bool>(mockFlutterConfig.getValue(flutterWebFeature.configSetting) as bool)
          .thenReturn(true);
      final Usage usage = Usage(runningOnBot: true);
      usage.sendCommand('test');

      final String featuresKey = cdKey(CustomDimensions.enabledFlutterFeatures);

      expect(globals.fs.file('test').readAsStringSync(), contains('$featuresKey: enable-web'));
    }, overrides: <Type, Generator>{
      FlutterVersion: () => FlutterVersion(const SystemClock()),
      Config: () => mockFlutterConfig,
      Platform: () => FakePlatform(environment: <String, String>{
        'FLUTTER_ANALYTICS_LOG_FILE': 'test',
      }),
      FileSystem: () => MemoryFileSystem(),
      ProcessManager: () => FakeProcessManager.any(),
    });

    testUsingContext('Usage records multiple features in experiment setting', () async {
      when<bool>(mockFlutterConfig.getValue(flutterWebFeature.configSetting) as bool)
          .thenReturn(true);
      when<bool>(mockFlutterConfig.getValue(flutterLinuxDesktopFeature.configSetting) as bool)
          .thenReturn(true);
      when<bool>(mockFlutterConfig.getValue(flutterMacOSDesktopFeature.configSetting) as bool)
          .thenReturn(true);
      final Usage usage = Usage(runningOnBot: true);
      usage.sendCommand('test');

      final String featuresKey = cdKey(CustomDimensions.enabledFlutterFeatures);

      expect(
        globals.fs.file('test').readAsStringSync(),
        contains('$featuresKey: enable-web,enable-linux-desktop,enable-macos-desktop'),
      );
    }, overrides: <Type, Generator>{
      FlutterVersion: () => FlutterVersion(const SystemClock()),
      Config: () => mockFlutterConfig,
      Platform: () => FakePlatform(environment: <String, String>{
        'FLUTTER_ANALYTICS_LOG_FILE': 'test',
      }),
      FileSystem: () => MemoryFileSystem(),
      ProcessManager: () => FakeProcessManager.any(),
    });
  });

  group('analytics with mocks', () {
    MemoryFileSystem memoryFileSystem;
    MockStdio mockStdio;
    Usage mockUsage;
    SystemClock mockClock;
    Doctor mockDoctor;
    List<int> mockTimes;

    setUp(() {
      memoryFileSystem = MemoryFileSystem();
      mockStdio = MockStdio();
      mockUsage = MockUsage();
      when(mockUsage.isFirstRun).thenReturn(false);
      mockClock = MockClock();
      mockDoctor = MockDoctor();
      when(mockClock.now()).thenAnswer(
        (Invocation _) => DateTime.fromMillisecondsSinceEpoch(mockTimes.removeAt(0))
      );
    });

    testUsingContext('flutter commands send timing events', () async {
      mockTimes = <int>[1000, 2000];
      when(mockDoctor.diagnose(
        androidLicenses: false,
        verbose: false,
      )).thenAnswer((_) async => true);
      final DoctorCommand command = DoctorCommand();
      final CommandRunner<void> runner = createTestCommandRunner(command);
      await runner.run(<String>['doctor']);

      verify(mockClock.now()).called(2);

      expect(
        verify(mockUsage.sendTiming(
          captureAny,
          captureAny,
          captureAny,
          label: captureAnyNamed('label'),
        )).captured,
        <dynamic>['flutter', 'doctor', const Duration(milliseconds: 1000), 'success'],
      );
    }, overrides: <Type, Generator>{
      SystemClock: () => mockClock,
      Doctor: () => mockDoctor,
      Usage: () => mockUsage,
    });

    testUsingContext('doctor fail sends warning', () async {
      mockTimes = <int>[1000, 2000];
      when(mockDoctor.diagnose(androidLicenses: false, verbose: false)).thenAnswer((_) async => false);
      final DoctorCommand command = DoctorCommand();
      final CommandRunner<void> runner = createTestCommandRunner(command);
      await runner.run(<String>['doctor']);

      verify(mockClock.now()).called(2);

      expect(
        verify(mockUsage.sendTiming(
          captureAny,
          captureAny,
          captureAny,
          label: captureAnyNamed('label'),
        )).captured,
        <dynamic>['flutter', 'doctor', const Duration(milliseconds: 1000), 'warning'],
      );
    }, overrides: <Type, Generator>{
      SystemClock: () => mockClock,
      Doctor: () => mockDoctor,
      Usage: () => mockUsage,
    });

    testUsingContext('single command usage path', () async {
      final FlutterCommand doctorCommand = DoctorCommand();

      expect(await doctorCommand.usagePath, 'doctor');
    }, overrides: <Type, Generator>{
      Usage: () => mockUsage,
    });

    testUsingContext('compound command usage path', () async {
      final BuildCommand buildCommand = BuildCommand();
      final FlutterCommand buildApkCommand = buildCommand.subcommands['apk'] as FlutterCommand;

      expect(await buildApkCommand.usagePath, 'build/apk');
    }, overrides: <Type, Generator>{
      Usage: () => mockUsage,
    });

    testUsingContext('command sends localtime', () async {
      const int kMillis = 1000;
      mockTimes = <int>[kMillis];
      // Since FLUTTER_ANALYTICS_LOG_FILE is set in the environment, analytics
      // will be written to a file.
      final Usage usage = Usage(
        versionOverride: 'test',
        runningOnBot: true,
      );
      usage.suppressAnalytics = false;
      usage.enabled = true;

      usage.sendCommand('test');

      final String log = globals.fs.file('analytics.log').readAsStringSync();
      final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(kMillis);

      expect(log.contains(formatDateTime(dateTime)), isTrue);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => FakeProcessManager.any(),
      SystemClock: () => mockClock,
      Platform: () => FakePlatform(
        environment: <String, String>{
          'FLUTTER_ANALYTICS_LOG_FILE': 'analytics.log',
        },
      ),
      Stdio: () => mockStdio,
    });

    testUsingContext('event sends localtime', () async {
      const int kMillis = 1000;
      mockTimes = <int>[kMillis];
      // Since FLUTTER_ANALYTICS_LOG_FILE is set in the environment, analytics
      // will be written to a file.
      final Usage usage = Usage(
        versionOverride: 'test',
        runningOnBot: true,
      );
      usage.suppressAnalytics = false;
      usage.enabled = true;

      usage.sendEvent('test', 'test');

      final String log = globals.fs.file('analytics.log').readAsStringSync();
      final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(kMillis);

      expect(log.contains(formatDateTime(dateTime)), isTrue);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => FakeProcessManager.any(),
      SystemClock: () => mockClock,
      Platform: () => FakePlatform(
        environment: <String, String>{
          'FLUTTER_ANALYTICS_LOG_FILE': 'analytics.log',
        },
      ),
      Stdio: () => mockStdio,
    });
  });

  group('analytics bots', () {
    Directory tempDir;

    setUp(() {
      tempDir = globals.fs.systemTempDirectory.createTempSync(
        'flutter_tools_analytics_bots_test.',
      );
    });

    tearDown(() {
      tryToDelete(tempDir);
    });

    testUsingContext("don't send on bots with unknown version", () async {
      int count = 0;
      globals.flutterUsage.onSend.listen((Map<String, dynamic> data) => count++);
      await createTestCommandRunner().run(<String>['--version']);

      expect(count, 0);
    }, overrides: <Type, Generator>{
      Usage: () => Usage(
        settingsName: 'flutter_bot_test',
        versionOverride: 'dev/unknown',
        configDirOverride: tempDir.path,
        runningOnBot: false,
      ),
    });

    testUsingContext("don't send on bots even when opted in", () async {
      int count = 0;
      globals.flutterUsage.onSend.listen((Map<String, dynamic> data) => count++);
      globals.flutterUsage.enabled = true;
      await createTestCommandRunner().run(<String>['--version']);

      expect(count, 0);
    }, overrides: <Type, Generator>{
      Usage: () => Usage(
        settingsName: 'flutter_bot_test',
        versionOverride: 'dev/unknown',
        configDirOverride: tempDir.path,
        runningOnBot: false,
      ),
    });

    testUsingContext('Uses AnalyticsMock when .flutter cannot be created', () async {
      final Usage usage = Usage(
        settingsName: 'flutter_bot_test',
        versionOverride: 'dev/known',
        configDirOverride: tempDir.path,
        analyticsIOFactory: throwingAnalyticsIOFactory,
        runningOnBot: false,
      );
      final AnalyticsMock analyticsMock = AnalyticsMock();

      expect(usage.clientId, analyticsMock.clientId);
      expect(usage.suppressAnalytics, isTrue);
    });
  });
}

Analytics throwingAnalyticsIOFactory(
  String trackingId,
  String applicationName,
  String applicationVersion, {
  String analyticsUrl,
  Directory documentDirectory,
}) {
  throw const FileSystemException('Could not create file');
}

class MockUsage extends Mock implements Usage {}

class MockDoctor extends Mock implements Doctor {}

class MockFlutterConfig extends Mock implements Config {}
