// 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 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
import 'package:meta/meta.dart';

import '../convert.dart';
import '../persistent_tool_state.dart';

/// This message is displayed on the first run of the Flutter tool, or anytime
/// that the contents of this string change.
const String _kFlutterFirstRunMessage = '''
  ╔════════════════════════════════════════════════════════════════════════════╗
  ║                 Welcome to Flutter! - https://flutter.dev                  ║
  ║                                                                            ║
  ║ The Flutter tool uses Google Analytics to anonymously report feature usage ║
  ║ statistics and basic crash reports. This data is used to help improve      ║
  ║ Flutter tools over time.                                                   ║
  ║                                                                            ║
  ║ Flutter tool analytics are not sent on the very first run. To disable      ║
  ║ reporting, type 'flutter config --no-analytics'. To display the current    ║
  ║ setting, type 'flutter config'. If you opt out of analytics, an opt-out    ║
  ║ event will be sent, and then no further information will be sent by the    ║
  ║ Flutter tool.                                                              ║
  ║                                                                            ║
  ║ By downloading the Flutter SDK, you agree to the Google Terms of Service.  ║
  ║ Note: The Google Privacy Policy describes how data is handled in this      ║
  ║ service.                                                                   ║
  ║                                                                            ║
  ║ Moreover, Flutter includes the Dart SDK, which may send usage metrics and  ║
  ║ crash reports to Google.                                                   ║
  ║                                                                            ║
  ║ Read about data we send with crash reports:                                ║
  ║ https://flutter.dev/docs/reference/crash-reporting                         ║
  ║                                                                            ║
  ║ See Google's privacy policy:                                               ║
  ║ https://policies.google.com/privacy                                        ║
  ╚════════════════════════════════════════════════════════════════════════════╝
''';

/// The first run messenger determines whether the first run license terms
/// need to be displayed.
class FirstRunMessenger {
  FirstRunMessenger({
    @required PersistentToolState persistentToolState
  }) : _persistentToolState = persistentToolState;

  final PersistentToolState _persistentToolState;

  /// Whether the license terms should be displayed.
  ///
  /// This is implemented by caching a hash of the previous license terms. This
  /// does not update the cache hash value.
  ///
  /// The persistent tool state setting [PersistentToolState.redisplayWelcomeMessage]
  /// can also be used to make this return false. This is primarily used to ensure
  /// that the license terms are not printed during a `flutter upgrade`, until the
  /// user manually runs the tool.
  bool shouldDisplayLicenseTerms() {
    if (_persistentToolState.redisplayWelcomeMessage == false) {
      return false;
    }
    final String oldHash = _persistentToolState.lastActiveLicenseTerms;
    return oldHash != _currentHash;
  }

  /// Update the cached license terms hash once the new terms have been displayed.
  void confirmLicenseTermsDisplayed() {
    _persistentToolState.lastActiveLicenseTerms = _currentHash;
  }

  /// The hash of the current license representation.
  String get _currentHash =>  hex.encode(md5.convert(utf8.encode(licenseTerms)).bytes);

  /// The current license terms.
  String get licenseTerms => _kFlutterFirstRunMessage;
}
