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

import 'base/common.dart';
import 'base/file_system.dart';
import 'base/logger.dart';
import 'base/platform.dart';
import 'base/process.dart';
import 'base/time.dart';
import 'base/utils.dart';
import 'cache.dart';
import 'convert.dart';
import 'features.dart';
import 'git.dart';
import 'globals.dart' as globals;

/// The default version when a version could not be determined.
const kUnknownFrameworkVersion = '0.0.0-unknown';

/// A git shortcut for the branch that is being tracked by the current one.
///
/// See `man gitrevisions` for more information.
const kGitTrackingUpstream = '@{upstream}';

/// Replacement name when the branch is user-specific.
const kUserBranch = '[user-branch]';

/// This maps old branch names to the names of branches that replaced them.
///
/// For example, in 2021 we deprecated the "dev" channel and transitioned "dev"
/// users to the "beta" channel.
const kObsoleteBranches = <String, String>{'dev': 'beta'};

/// The names of each channel/branch in order of increasing stability.
enum Channel { master, main, beta, stable }

// Beware: Keep order in accordance with stability
const kOfficialChannels = <String>{'master', 'main', 'beta', 'stable'};

const kChannelDescriptions = <String, String>{
  'master': 'latest development branch, for contributors',
  'main': 'latest development branch, follows master channel',
  'beta': 'updated monthly, recommended for experienced users',
  'stable': 'updated quarterly, for new users and for production app releases',
};

const kDevelopmentChannels = <String>{'master', 'main'};

/// Retrieve a human-readable name for a given [channel].
///
/// Requires [kOfficialChannels] to be correctly ordered.
String getNameForChannel(Channel channel) {
  return kOfficialChannels.elementAt(channel.index);
}

/// Retrieve the [Channel] representation for a string [name].
///
/// Returns `null` if [name] is not in the list of official channels, according
/// to [kOfficialChannels].
Channel? getChannelForName(String name) {
  if (kOfficialChannels.contains(name)) {
    return Channel.values[kOfficialChannels.toList().indexOf(name)];
  }
  return null;
}

abstract class FlutterVersion {
  /// Parses the Flutter version from currently available tags in the local
  /// repo.
  factory FlutterVersion({
    SystemClock clock = const SystemClock(),
    required FileSystem fs,
    required Git git,
    required String flutterRoot,
    @protected bool fetchTags = false,
  }) {
    final File versionFile = getVersionFile(fs, flutterRoot);

    if (!fetchTags && versionFile.existsSync()) {
      final _FlutterVersionFromFile? version = _FlutterVersionFromFile.tryParseFromFile(
        versionFile,
        git: git,
        flutterRoot: flutterRoot,
      );
      if (version != null) {
        final String gitPath = fs.path.join(flutterRoot, '.git');
        // In a standard git clone, .git is a directory. In a git worktree, .git is a file.
        final bool isGitRepo = fs.directory(gitPath).existsSync() || fs.file(gitPath).existsSync();
        if (!isGitRepo) {
          return version;
        }
        // If the cached version looks suspicious, we fall back to git detection.
        // This handles cases where the cache was poisoned by an app repo's git environment.
        final bool isSuspicious =
            version.frameworkVersion == kUnknownFrameworkVersion ||
            version.repositoryUrl == 'unknown source' ||
            !_isStandardRemote(version.repositoryUrl);
        if (!isSuspicious) {
          return version;
        }
      }
    }

    // if we are fetching tags, ignore cached versionFile
    if (fetchTags && versionFile.existsSync()) {
      versionFile.deleteSync();
      final File legacyVersionFile = fs.file(fs.path.join(flutterRoot, 'version'));
      if (legacyVersionFile.existsSync()) {
        legacyVersionFile.deleteSync();
      }
    }

    final String frameworkRevision = git
        .logSync(['-n', '1', '--pretty=format:%H'], workingDirectory: flutterRoot)
        .stdout
        .trim();

    return FlutterVersion.fromRevision(
      clock: clock,
      frameworkRevision: frameworkRevision,
      fs: fs,
      flutterRoot: flutterRoot,
      fetchTags: fetchTags,
      git: git,
    );
  }

  FlutterVersion._({
    required SystemClock clock,
    required Git git,
    required this.flutterRoot,
    required this.fs,
  }) : _clock = clock,
       _git = git;

  factory FlutterVersion.fromRevision({
    SystemClock clock = const SystemClock(),
    required String flutterRoot,
    required String frameworkRevision,
    required FileSystem fs,
    required Git git,
    bool fetchTags = false,
  }) {
    final GitTagVersion gitTagVersion = GitTagVersion.determine(
      globals.platform,
      git: git,
      gitRef: frameworkRevision,
      workingDirectory: flutterRoot,
      fetchTags: fetchTags,
    );
    final String frameworkVersion = gitTagVersion.frameworkVersionFor(frameworkRevision);
    final result = _FlutterVersionGit._(
      clock: clock,
      flutterRoot: flutterRoot,
      frameworkRevision: frameworkRevision,
      frameworkVersion: frameworkVersion,
      gitTagVersion: gitTagVersion,
      fs: fs,
      git: git,
    );
    if (fetchTags) {
      result.ensureVersionFile();
    }
    return result;
  }

  /// Ensure the latest git tags are fetched and recalculate [FlutterVersion].
  ///
  /// This is only required when not on beta or stable and we need to calculate
  /// the current version relative to upstream tags.
  ///
  /// This is a method and not a factory constructor so that test classes can
  /// override it.
  FlutterVersion fetchTagsAndGetVersion({SystemClock clock = const SystemClock()}) {
    // We don't need to fetch tags on beta and stable to calculate the version,
    // we should already exactly be on a tag that was pushed when this release
    // was published.
    if (channel != 'master' && channel != 'main') {
      return this;
    }
    return FlutterVersion(
      clock: clock,
      flutterRoot: flutterRoot,
      fs: fs,
      fetchTags: true,
      git: _git,
    );
  }

  final FileSystem fs;
  final Git _git;
  final SystemClock _clock;

  String? get repositoryUrl;

  GitTagVersion get gitTagVersion;

  /// The channel is the upstream branch.
  ///
  /// `master`, `dev`, `beta`, `stable`; or old ones, like `alpha`, `hackathon`, ...
  String get channel;

  /// The SHA describing the commit being used for the SDK and tools provide in `flutter/flutter`.
  ///
  /// The _exception_ is the _engine artifacts_, which are downloaded separately as [engineRevision].
  String get frameworkRevision;

  /// The shorter Git commit SHA of [frameworkRevision].
  String get frameworkRevisionShort => _shortGitRevision(frameworkRevision);
  String get frameworkVersion;

  String get devToolsVersion;
  String get dartSdkVersion;

  /// The SHA describing the commit being used for the engine artifacts, which are compiled from the `engine/` sub-directory.
  ///
  /// When using a standard release build, or master channel, [engineRevision] will be identical to [frameworkRevision] since
  /// the monorepository merge (as of 2025); however when modifying the framework (or engine) locally, or using a flag such
  /// as `FLUTTER_PREBUILT_ENGINE_VERSION=...`, the engine SHA will be _different_ than the [frameworkRevision].
  String get engineRevision;

  /// The hash produced by the source code responsible for engine artifacts being built.
  String? get engineContentHash;

  /// The shorter Git commit SHA of [engineRevision].
  String get engineRevisionShort => _shortGitRevision(engineRevision);

  // This is static as it is called from a constructor.
  static File getVersionFile(FileSystem fs, String flutterRoot) {
    return fs.file(fs.path.join(flutterRoot, 'bin', 'cache', 'flutter.version.json'));
  }

  final String flutterRoot;

  String _getTimeSinceCommit({String? revision}) {
    return _git
        .logSync(['-n', '1', '--pretty=format:%ar', ?revision], workingDirectory: flutterRoot)
        .stdout
        .trim();
  }

  // TODO(fujino): calculate this relative to frameworkCommitDate for
  // _FlutterVersionFromFile so we don't need a git call.
  late final String frameworkAge = _getTimeSinceCommit();
  late final String engineAge = engineBuildDate != null
      ? _clock.now().difference(DateTime.parse(engineBuildDate!)).ago()
      : _getTimeSinceCommit(revision: engineRevision);

  /// Populates bin/cache/flutter.version.json with the current version information, if it does not
  /// already exist.
  void ensureVersionFile();

  /// Deletes bin/cache/flutter.version.json so it can be regenerated on the next invocation of the
  /// tool.
  void deleteVersionFile() {
    final File versionFile = getVersionFile(fs, flutterRoot);
    if (versionFile.existsSync()) {
      versionFile.deleteSync();
    }
  }

  @override
  String toString() {
    final versionText = frameworkVersion == kUnknownFrameworkVersion ? '' : ' $frameworkVersion';
    final flutterText =
        'Flutter$versionText • channel $channel • ${repositoryUrl ?? 'unknown source'}';
    final frameworkText =
        'Framework • revision $frameworkRevisionShort ($frameworkAge) • $frameworkCommitDate';
    String engineText;
    if (engineContentHash != null) {
      engineText = 'Engine • hash $engineContentHash (revision $engineRevisionShort) ($engineAge)';
    } else {
      engineText = 'Engine • revision $engineRevisionShort ($engineAge)';
    }
    if (engineCommitDate != null) {
      engineText = '$engineText • $engineCommitDate';
    }

    final toolsText = 'Tools • Dart $dartSdkVersion • DevTools $devToolsVersion';

    // Flutter 1.10.2-pre.69 • channel master • https://github.com/flutter/flutter.git
    // Framework • revision 340c158f32 (85 minutes ago) • 2018-10-26 11:27:22 -0400
    // Engine • revision 9c46333e14 (96 minutes ago) • 2018-10-26 11:16:22 -0400
    // Tools • Dart 2.1.0 (build 2.1.0-dev.8.0 bf26f760b1)

    return '$flutterText\n$frameworkText\n$engineText\n$toolsText';
  }

  Map<String, Object> toJson() => <String, Object>{
    'frameworkVersion': frameworkVersion,
    'channel': channel,
    'repositoryUrl': repositoryUrl ?? 'unknown source',
    'frameworkRevision': frameworkRevision,
    'frameworkCommitDate': frameworkCommitDate,
    'engineRevision': engineRevision,
    'engineCommitDate': ?engineCommitDate,
    'engineContentHash': ?engineContentHash,
    'engineBuildDate': ?engineBuildDate,
    'dartSdkVersion': dartSdkVersion,
    'devToolsVersion': devToolsVersion,
    'flutterVersion': frameworkVersion,
  };

  /// A date String describing the [frameworkRevision] commit.
  ///
  /// If a git command fails, this will return a placeholder date.
  String get frameworkCommitDate;

  /// A date String describing the [engineRevision] commit.
  ///
  /// If a git command fails, this will return a placeholder date.
  ///
  /// If no date was recorded ([engineCommitDate] is a newly stored field),
  /// the date is omitted, and left `null`.
  String? get engineCommitDate;

  /// A date String describing the [engineRevision] build time.
  ///
  /// If no date was recorded ([engineCommitDate] is a newly stored field),
  /// the date is omitted, and left `null`.
  String? get engineBuildDate;

  /// Checks if the currently installed version of Flutter is up-to-date, and
  /// warns the user if it isn't.
  ///
  /// This function must run while [Cache.lock] is acquired because it reads and
  /// writes shared cache files.
  Future<void> checkFlutterVersionFreshness() async {
    // Don't perform update checks if we're not on an official channel.
    if (!kOfficialChannels.contains(channel)) {
      return;
    }
    // Don't perform the update check if the tracking remote is not standard.
    if (VersionUpstreamValidator(version: this, platform: globals.platform).run() != null) {
      return;
    }
    DateTime localFrameworkCommitDate;
    try {
      // Don't perform the update check if fetching the latest local commit failed.
      localFrameworkCommitDate = DateTime.parse(
        _gitCommitDate(git: _git, workingDirectory: flutterRoot),
      );
    } on VersionCheckError {
      return;
    } on FormatException {
      return;
    }
    final DateTime? latestFlutterCommitDate = await _getLatestAvailableFlutterDate();

    return VersionFreshnessValidator(
      version: this,
      clock: _clock,
      localFrameworkCommitDate: localFrameworkCommitDate,
      latestFlutterCommitDate: latestFlutterCommitDate,
      logger: globals.logger,
      cache: globals.cache,
      pauseTime: VersionFreshnessValidator.timeToPauseToLetUserReadTheMessage,
    ).run();
  }

  /// Gets the release date of the latest available Flutter version.
  ///
  /// This method sends a server request if it's been more than
  /// [VersionFreshnessValidator.checkAgeConsideredUpToDate] since
  /// the last version check.
  ///
  /// Returns `null` if the cached version is out-of-date or missing, and we are
  /// unable to reach the server to get the latest version.
  Future<DateTime?> _getLatestAvailableFlutterDate() async {
    globals.cache.checkLockAcquired();
    final VersionCheckStamp versionCheckStamp = await VersionCheckStamp.load(
      globals.cache,
      globals.logger,
    );

    final DateTime now = _clock.now();
    if (versionCheckStamp.lastTimeVersionWasChecked != null) {
      final Duration timeSinceLastCheck = now.difference(
        versionCheckStamp.lastTimeVersionWasChecked!,
      );

      // Don't ping the server too often. Return cached value if it's fresh.
      if (timeSinceLastCheck < VersionFreshnessValidator.checkAgeConsideredUpToDate) {
        return versionCheckStamp.lastKnownRemoteVersion;
      }
    }

    // Cache is empty or it's been a while since the last server ping. Ping the server.
    try {
      final DateTime remoteFrameworkCommitDate = DateTime.parse(
        await _fetchRemoteFrameworkCommitDate(),
      );
      await versionCheckStamp.store(
        newTimeVersionWasChecked: now,
        newKnownRemoteVersion: remoteFrameworkCommitDate,
      );
      return remoteFrameworkCommitDate;
    } on VersionCheckError catch (error) {
      // This happens when any of the git commands fails, which can happen when
      // there's no Internet connectivity. Remote version check is best effort
      // only. We do not prevent the command from running when it fails.
      globals.printTrace('Failed to check Flutter version in the remote repository: $error');
      // Still update the timestamp to avoid us hitting the server on every single
      // command if for some reason we cannot connect (eg. we may be offline).
      await versionCheckStamp.store(newTimeVersionWasChecked: now);
      return null;
    }
  }

  /// The date of the latest framework commit in the remote repository.
  ///
  /// Throws [VersionCheckError] if a git command fails, for example, when the
  /// remote git repository is not reachable due to a network issue.
  Future<String> _fetchRemoteFrameworkCommitDate() async {
    try {
      // Fetch upstream branch's commit and tags
      await _run(_git, ['fetch', '--tags']);
      return _gitCommitDate(
        git: _git,
        gitRef: kGitTrackingUpstream,
        workingDirectory: Cache.flutterRoot,
      );
    } on VersionCheckError catch (error) {
      globals.printError(error.message);
      rethrow;
    }
  }

  /// Return a short string for the version (e.g. `master/0.0.59-pre.92`, `scroll_refactor/a76bc8e22b`).
  String getVersionString({bool redactUnknownBranches = false}) {
    if (frameworkVersion != kUnknownFrameworkVersion) {
      return '${getBranchName(redactUnknownBranches: redactUnknownBranches)}/$frameworkVersion';
    }
    return '${getBranchName(redactUnknownBranches: redactUnknownBranches)}/$frameworkRevisionShort';
  }

  /// The name of the local branch.
  ///
  /// Use getBranchName() to read this.
  String? _branch;

  /// Return the branch name.
  ///
  /// If [redactUnknownBranches] is true and the branch is unknown,
  /// the branch name will be returned as `'[user-branch]'` ([kUserBranch]).
  String getBranchName({bool redactUnknownBranches = false}) {
    _branch ??= () {
      final String branch = _git
          .runSync(['symbolic-ref', '--short', 'HEAD'], workingDirectory: flutterRoot)
          .stdout
          .trim();
      return branch == 'HEAD' ? '' : branch;
    }();
    if (redactUnknownBranches || _branch!.isEmpty) {
      // Only return the branch names we know about; arbitrary branch names might contain PII.
      if (!kOfficialChannels.contains(_branch) && !kObsoleteBranches.containsKey(_branch)) {
        return kUserBranch;
      }
    }
    return _branch!;
  }

  /// Reset the version freshness information by removing the stamp file.
  ///
  /// New version freshness information will be regenerated when
  /// [checkFlutterVersionFreshness] is called after this. This is typically
  /// used when switching channels so that stale information from another
  /// channel doesn't linger.
  static Future<void> resetFlutterVersionFreshnessCheck() async {
    try {
      await globals.cache.getStampFileFor(VersionCheckStamp.flutterVersionCheckStampFile).delete();
    } on FileSystemException {
      // Ignore, since we don't mind if the file didn't exist in the first place.
    }
  }
}

// The date of the given commit hash as [gitRef]. If no hash is specified,
// then it is the HEAD of the current local branch.
//
// If lenient is true, and the git command fails, a placeholder date is
// returned. Otherwise, the VersionCheckError exception is propagated.
String _gitCommitDate({
  String gitRef = 'HEAD',
  bool lenient = false,
  required Git git,
  required String? workingDirectory,
}) {
  final RunResult result = git.logSync([
    gitRef,
    '-n',
    '1',
    '--pretty=format:%ad',
    '--date=iso',
  ], workingDirectory: workingDirectory);
  if (result.exitCode == 0) {
    return result.stdout.trim();
  }
  final error = VersionCheckError(
    'Command exited with code ${result.exitCode}: ${result.command.join(' ')}\n'
    'Standard out: ${result.stdout}\n'
    'Standard error: ${result.stderr}',
  );
  if (lenient) {
    final dummyDate = DateTime.fromMillisecondsSinceEpoch(0);
    globals.printError(
      'Failed to find the latest git commit date: $error\n'
      'Returning $dummyDate instead.',
    );
    // Return something that DateTime.parse() can parse.
    return dummyDate.toString();
  }
  throw error;
}

class _FlutterVersionFromFile extends FlutterVersion {
  _FlutterVersionFromFile._({
    required super.clock,
    required this.frameworkVersion,
    required this.channel,
    required this.repositoryUrl,
    required this.frameworkRevision,
    required this.frameworkCommitDate,
    required this.engineRevision,
    required this.engineCommitDate,
    required this.dartSdkVersion,
    required this.devToolsVersion,
    required this.gitTagVersion,
    required this.engineContentHash,
    required this.engineBuildDate,
    required super.flutterRoot,
    required super.fs,
    required super.git,
  }) : super._();

  static _FlutterVersionFromFile? tryParseFromFile(
    File jsonFile, {
    required String flutterRoot,
    required Git git,
    SystemClock clock = const SystemClock(),
  }) {
    try {
      final String jsonContents = jsonFile.readAsStringSync();
      final manifest = jsonDecode(jsonContents) as Map<String, Object?>;

      return _FlutterVersionFromFile._(
        clock: clock,
        git: git,
        frameworkVersion: manifest['frameworkVersion']! as String,
        channel: manifest['channel']! as String,
        repositoryUrl: manifest['repositoryUrl']! as String,
        frameworkRevision: manifest['frameworkRevision']! as String,
        frameworkCommitDate: manifest['frameworkCommitDate']! as String,
        engineRevision: manifest['engineRevision']! as String,
        engineCommitDate: manifest['engineCommitDate'] as String?,
        engineContentHash: manifest['engineContentHash'] as String?,
        engineBuildDate: manifest['engineBuildDate'] as String?,
        dartSdkVersion: manifest['dartSdkVersion']! as String,
        devToolsVersion: manifest['devToolsVersion']! as String,
        gitTagVersion: GitTagVersion.parse(manifest['flutterVersion']! as String),
        flutterRoot: flutterRoot,
        fs: jsonFile.fileSystem,
      );
      // ignore: avoid_catches_without_on_clauses
    } catch (err) {
      globals.printTrace('Failed to parse ${jsonFile.path} with $err');
      try {
        jsonFile.deleteSync();
      } on FileSystemException {
        globals.printTrace('Failed to delete ${jsonFile.path}');
      }
      // Returning null means fallback to git implementation.
      return null;
    }
  }

  @override
  final GitTagVersion gitTagVersion;

  @override
  final String frameworkVersion;

  @override
  final String channel;

  @override
  String getBranchName({bool redactUnknownBranches = false}) => channel;

  @override
  final String repositoryUrl;

  @override
  final String frameworkRevision;

  @override
  final String frameworkCommitDate;

  @override
  final String? engineCommitDate;

  @override
  final String? engineBuildDate;

  @override
  final String engineRevision;

  @override
  final String? engineContentHash;

  @override
  final String dartSdkVersion;

  @override
  final String devToolsVersion;

  @override
  void ensureVersionFile() {
    _ensureLegacyVersionFile(fs: fs, flutterRoot: flutterRoot, frameworkVersion: frameworkVersion);
  }
}

class _FlutterVersionGit extends FlutterVersion {
  _FlutterVersionGit._({
    required super.clock,
    required super.flutterRoot,
    required this.frameworkRevision,
    required this.frameworkVersion,
    required this.gitTagVersion,
    required super.fs,
    required super.git,
  }) : super._();

  late final FlutterEngineStampFromFile? _engineStamp = FlutterEngineStampFromFile.tryParseFromFile(
    fs.file(fs.path.join(flutterRoot, 'bin', 'cache', 'engine_stamp.json')),
  );

  @override
  final GitTagVersion gitTagVersion;

  @override
  final String frameworkRevision;

  @override
  String get frameworkCommitDate =>
      _gitCommitDate(git: _git, lenient: true, workingDirectory: flutterRoot);

  // This uses 'late final' instead of 'String get' because unlike frameworkCommitDate, it is
  // operating based on a 'gitRef: ...', which we can assume to be immutable in the context of
  // this invocation (possibly HEAD could change, but gitRef should not).
  @override
  late final String engineCommitDate =
      _engineStamp?.gitRevisionDate.toString() ??
      _gitCommitDate(
        git: _git,
        gitRef: engineRevision,
        lenient: true,
        workingDirectory: flutterRoot,
      );

  String? _repositoryUrl;
  @override
  String? get repositoryUrl {
    if (_repositoryUrl == null) {
      final RunResult trackingResult = _git.runSync([
        'rev-parse',
        '--abbrev-ref',
        '--symbolic',
        kGitTrackingUpstream,
      ], workingDirectory: flutterRoot);
      if (trackingResult.exitCode == 0) {
        final String gitChannel = trackingResult.stdout.trim();
        final int slash = gitChannel.indexOf('/');
        if (slash != -1) {
          final String remote = gitChannel.substring(0, slash);
          final RunResult remoteResult = _git.runSync([
            'ls-remote',
            '--get-url',
            remote,
          ], workingDirectory: flutterRoot);
          if (remoteResult.exitCode == 0) {
            _repositoryUrl = remoteResult.stdout.trim();
          }
        }
      }
      if (_repositoryUrl == null || _repositoryUrl!.isEmpty) {
        final RunResult originResult = _git.runSync([
          'remote',
          'get-url',
          'origin',
        ], workingDirectory: flutterRoot);
        if (originResult.exitCode == 0) {
          _repositoryUrl = originResult.stdout.trim();
        }
      }
    }
    return _repositoryUrl;
  }

  @override
  String get devToolsVersion => globals.cache.devToolsVersion;

  @override
  String get dartSdkVersion => globals.cache.dartSdkVersion;

  @override
  String get engineRevision => _engineStamp?.gitRevision ?? globals.cache.engineRevision;

  @override
  final String frameworkVersion;

  /// The channel is the current branch if we recognize it, or "[user-branch]" (kUserBranch).
  /// `master`, `beta`, `stable`; or old ones, like `alpha`, `hackathon`, `dev`, ...
  @override
  String get channel {
    final String channel = getBranchName(redactUnknownBranches: true);
    assert(
      kOfficialChannels.contains(channel) ||
          kObsoleteBranches.containsKey(channel) ||
          channel == kUserBranch,
      'Potential PII leak in channel name: "$channel"',
    );
    return channel;
  }

  @override
  void ensureVersionFile() {
    _ensureLegacyVersionFile(fs: fs, flutterRoot: flutterRoot, frameworkVersion: frameworkVersion);
    const encoder = JsonEncoder.withIndent('  ');
    final File newVersionFile = FlutterVersion.getVersionFile(fs, flutterRoot);
    newVersionFile.writeAsStringSync(encoder.convert(toJson()));
  }

  @override
  String? get engineBuildDate => _engineStamp?.buildDate.toString();

  @override
  String? get engineContentHash => _engineStamp?.contentHash;
}

void _ensureLegacyVersionFile({
  required FileSystem fs,
  required String flutterRoot,
  required String frameworkVersion,
}) {
  // TODO(matanlurey): https://github.com/flutter/flutter/issues/171900.
  if (featureFlags.isOmitLegacyVersionFileEnabled) {
    return;
  }
  final File legacyVersionFile = fs.file(fs.path.join(flutterRoot, 'version'));
  if (!legacyVersionFile.existsSync()) {
    legacyVersionFile.writeAsStringSync(frameworkVersion);
  }
}

/// Checks if the provided [version] is tracking a standard remote.
///
/// A "standard remote" is one having the same url as(in order of precedence):
///  * The value of `FLUTTER_GIT_URL` environment variable.
///  * The HTTPS or SSH url of the Flutter repository as provided by GitHub.
///
/// To initiate the validation check, call [run].
///
/// This prevents the tool to check for version freshness from the standard
/// remote but fetch updates from the upstream of current branch/channel, both
/// of which can be different.
///
/// This also prevents unnecessary freshness check from a forked repo unless the
/// user explicitly configures the environment to do so.
class VersionUpstreamValidator {
  VersionUpstreamValidator({required this.version, required this.platform});

  final Platform platform;
  final FlutterVersion version;

  /// Performs the validation against the tracking remote of the [version].
  ///
  /// Returns [VersionCheckError] if the tracking remote is not standard.
  VersionCheckError? run() {
    final String? flutterGit = platform.environment['FLUTTER_GIT_URL'];
    final String? repositoryUrl = version.repositoryUrl;

    if (repositoryUrl == null) {
      return VersionCheckError(
        'The tool could not determine the remote upstream which is being '
        'tracked by the SDK.',
      );
    }

    // Strip `.git` suffix before comparing the remotes
    final List<String> sanitizedStandardRemotes = [
      // If `FLUTTER_GIT_URL` is set, use that as standard remote.
      if (flutterGit != null)
        flutterGit
      // Else use the predefined standard remotes.
      else
        ..._standardRemotes,
    ].map((String remote) => stripDotGit(remote)).toList();

    final String sanitizedRepositoryUrl = stripDotGit(repositoryUrl);

    if (!sanitizedStandardRemotes.contains(sanitizedRepositoryUrl)) {
      if (flutterGit != null) {
        // If `FLUTTER_GIT_URL` is set, inform to either remove the
        // `FLUTTER_GIT_URL` environment variable or set it to the current
        // tracking remote.
        return VersionCheckError(
          'The Flutter SDK is tracking "$repositoryUrl" but "FLUTTER_GIT_URL" '
          'is set to "$flutterGit".\n'
          'Either remove "FLUTTER_GIT_URL" from the environment or set it to '
          '"$repositoryUrl". '
          'If this is intentional, it is recommended to use "git" directly to '
          'manage the SDK.',
        );
      }
      // If `FLUTTER_GIT_URL` is unset, inform to set the environment variable.
      return VersionCheckError(
        'The Flutter SDK is tracking a non-standard remote "$repositoryUrl".\n'
        'Set the environment variable "FLUTTER_GIT_URL" to '
        '"$repositoryUrl". '
        'If this is intentional, it is recommended to use "git" directly to '
        'manage the SDK.\n'
        r'If this is NOT intentional, try deleting the version cache: `rm $FLUTTER_ROOT/bin/cache/flutter.version.json`.',
      );
    }
    return null;
  }

  // The predefined list of remotes that are considered to be standard.
  static final _standardRemotes = [
    'https://github.com/flutter/flutter.git',
    'git@github.com:flutter/flutter.git',
    'ssh://git@github.com/flutter/flutter.git',
  ];

  // Strips ".git" suffix from a given string, preferably an url.
  // For example, changes 'https://github.com/flutter/flutter.git' to 'https://github.com/flutter/flutter'.
  // URLs without ".git" suffix will remain unaffected.
  static final _patternUrlDotGit = RegExp(r'(.*)(\.git)$');
  static String stripDotGit(String url) {
    return _patternUrlDotGit.firstMatch(url)?.group(1)! ?? url;
  }
}

/// Contains data and load/save logic pertaining to Flutter version checks.
@visibleForTesting
class VersionCheckStamp {
  const VersionCheckStamp({
    this.lastTimeVersionWasChecked,
    this.lastKnownRemoteVersion,
    this.lastTimeWarningWasPrinted,
  });

  final DateTime? lastTimeVersionWasChecked;
  final DateTime? lastKnownRemoteVersion;
  final DateTime? lastTimeWarningWasPrinted;

  /// The prefix of the stamp file where we cache Flutter version check data.
  @visibleForTesting
  static const flutterVersionCheckStampFile = 'flutter_version_check';

  static Future<VersionCheckStamp> load(Cache cache, Logger logger) async {
    final String? versionCheckStamp = cache.getStampFor(flutterVersionCheckStampFile);

    if (versionCheckStamp != null) {
      // Attempt to parse stamp JSON.
      try {
        final dynamic jsonObject = json.decode(versionCheckStamp);
        if (jsonObject is Map<String, dynamic>) {
          return fromJson(jsonObject);
        } else {
          logger.printTrace('Warning: expected version stamp to be a Map but found: $jsonObject');
        }
      } on Exception catch (error, stackTrace) {
        // Do not crash if JSON is malformed.
        logger.printTrace('${error.runtimeType}: $error\n$stackTrace');
      }
    }

    // Stamp is missing or is malformed.
    return const VersionCheckStamp();
  }

  static VersionCheckStamp fromJson(Map<String, dynamic> jsonObject) {
    DateTime? readDateTime(String property) {
      return jsonObject.containsKey(property)
          ? DateTime.parse(jsonObject[property] as String)
          : null;
    }

    return VersionCheckStamp(
      lastTimeVersionWasChecked: readDateTime('lastTimeVersionWasChecked'),
      lastKnownRemoteVersion: readDateTime('lastKnownRemoteVersion'),
      lastTimeWarningWasPrinted: readDateTime('lastTimeWarningWasPrinted'),
    );
  }

  Future<void> store({
    DateTime? newTimeVersionWasChecked,
    DateTime? newKnownRemoteVersion,
    DateTime? newTimeWarningWasPrinted,
    Cache? cache,
  }) async {
    final Map<String, String> jsonData = toJson();

    if (newTimeVersionWasChecked != null) {
      jsonData['lastTimeVersionWasChecked'] = '$newTimeVersionWasChecked';
    }

    if (newKnownRemoteVersion != null) {
      jsonData['lastKnownRemoteVersion'] = '$newKnownRemoteVersion';
    }

    if (newTimeWarningWasPrinted != null) {
      jsonData['lastTimeWarningWasPrinted'] = '$newTimeWarningWasPrinted';
    }

    const prettyJsonEncoder = JsonEncoder.withIndent('  ');
    (cache ?? globals.cache).setStampFor(
      flutterVersionCheckStampFile,
      prettyJsonEncoder.convert(jsonData),
    );
  }

  Map<String, String> toJson({
    DateTime? updateTimeVersionWasChecked,
    DateTime? updateKnownRemoteVersion,
    DateTime? updateTimeWarningWasPrinted,
  }) {
    updateTimeVersionWasChecked = updateTimeVersionWasChecked ?? lastTimeVersionWasChecked;
    updateKnownRemoteVersion = updateKnownRemoteVersion ?? lastKnownRemoteVersion;
    updateTimeWarningWasPrinted = updateTimeWarningWasPrinted ?? lastTimeWarningWasPrinted;

    final jsonData = <String, String>{};

    if (updateTimeVersionWasChecked != null) {
      jsonData['lastTimeVersionWasChecked'] = '$updateTimeVersionWasChecked';
    }

    if (updateKnownRemoteVersion != null) {
      jsonData['lastKnownRemoteVersion'] = '$updateKnownRemoteVersion';
    }

    if (updateTimeWarningWasPrinted != null) {
      jsonData['lastTimeWarningWasPrinted'] = '$updateTimeWarningWasPrinted';
    }

    return jsonData;
  }
}

/// Thrown when we fail to check Flutter version.
///
/// This can happen when we attempt to `git fetch` but there is no network, or
/// when the installation is not git-based (e.g. a user clones the repo but
/// then removes .git).
class VersionCheckError implements Exception {
  VersionCheckError(this.message);

  final String message;

  @override
  String toString() => '$VersionCheckError: $message';
}

/// Runs [command] in the root of the Flutter installation and returns the
/// standard output as a string.
///
/// If the command fails, throws a [ToolExit] exception.
Future<String> _run(Git git, List<String> command) async {
  // TODO(matanlurey): Inline this in the single place it's called in this file.
  final RunResult results = await git.run(command, workingDirectory: Cache.flutterRoot);

  if (results.exitCode == 0) {
    return results.stdout.trim();
  }

  throw VersionCheckError(
    'Command exited with code ${results.exitCode}: ${command.join(' ')}\n'
    'Standard error: ${results.stderr}',
  );
}

String _shortGitRevision(String? revision) {
  if (revision == null) {
    return '';
  }
  return revision.length > 10 ? revision.substring(0, 10) : revision;
}

/// Version of Flutter SDK parsed from Git.
class GitTagVersion {
  const GitTagVersion({
    required this.x,
    required this.y,
    required this.z,
    required this.hash,
    required this.gitTag,
    this.hotfix,
    this.devVersion,
    this.devPatch,
    this.commits,
  });
  const GitTagVersion.unknown()
    : x = null,
      y = null,
      z = null,
      hotfix = null,
      commits = 0,
      devVersion = null,
      devPatch = null,
      hash = '',
      gitTag = '';

  /// The X in vX.Y.Z.
  final int? x;

  /// The Y in vX.Y.Z.
  final int? y;

  /// The Z in vX.Y.Z.
  final int? z;

  /// the F in vX.Y.Z+hotfix.F.
  final int? hotfix;

  /// Number of commits since the vX.Y.Z tag.
  final int? commits;

  /// The git hash (or an abbreviation thereof) for this commit.
  final String hash;

  /// The N in X.Y.Z-dev.N.M.
  final int? devVersion;

  /// The M in X.Y.Z-dev.N.M.
  final int? devPatch;

  /// The git tag that is this version's closest ancestor.
  final String gitTag;

  static GitTagVersion determine(
    Platform platform, {
    required Git git,
    String? workingDirectory,
    bool fetchTags = false,
    String gitRef = 'HEAD',
  }) {
    if (fetchTags) {
      final String channel = git
          .runSync(['symbolic-ref', '--short', 'HEAD'], workingDirectory: workingDirectory)
          .stdout
          .trim();
      if (!kDevelopmentChannels.contains(channel) && kOfficialChannels.contains(channel)) {
        globals.printTrace('Skipping request to fetchTags - on well known channel $channel.');
      } else {
        final String flutterGit =
            platform.environment['FLUTTER_GIT_URL'] ?? 'https://github.com/flutter/flutter.git';
        git.runSync(['fetch', flutterGit, '--tags', '-f'], workingDirectory: workingDirectory);
      }
    }
    // find all tags attached to the given [gitRef]. These are returned in alphabetical order, so
    // we reverse the set of tags to examine the most recent tag versions first.
    final List<String> tags = git
        .runSync(['tag', '--points-at', gitRef], workingDirectory: workingDirectory)
        .stdout
        .trim()
        .split('\n')
        .reversed
        .toList();

    // Check first for a stable tag
    final stableTagPattern = RegExp(r'^\d+\.\d+\.\d+$');
    for (final tag in tags) {
      if (stableTagPattern.hasMatch(tag.trim())) {
        return parse(tag);
      }
    }
    // Next check for a dev tag
    final devTagPattern = RegExp(r'^\d+\.\d+\.\d+-\d+\.\d+\.pre$');
    for (final tag in tags) {
      if (devTagPattern.hasMatch(tag.trim())) {
        return parse(tag);
      }
    }

    // If we don't exist in a tag, use git to find the latest tag.
    return _useNewestTagAndCommitsPastFallback(
      git: git,
      workingDirectory: workingDirectory,
      gitRef: gitRef,
    );
  }

  static GitTagVersion _useNewestTagAndCommitsPastFallback({
    required Git git,
    required String? workingDirectory,
    required String gitRef,
  }) {
    final String latestTag = git
        .runSync([
          'for-each-ref',
          '--sort=-v:refname',
          '--count=1',
          '--format=%(refname:short)',
          'refs/tags/[0-9]*.*.*',
        ], workingDirectory: workingDirectory)
        .stdout
        .trim();

    final String ancestorRef = git
        .runSync(['merge-base', gitRef, latestTag], workingDirectory: workingDirectory)
        .stdout
        .trim();

    final String commitCount = git
        .runSync([
          'rev-list',
          '--count',
          '$ancestorRef..$gitRef',
        ], workingDirectory: workingDirectory)
        .stdout
        .trim();

    return parse('$latestTag-$commitCount');
  }

  /// Parse a version string.
  ///
  /// The version string can either be an exact release tag (e.g. '1.2.3' for
  /// stable or 1.2.3-4.5.pre for a dev) or the output of `git describe` (e.g.
  /// for commit abc123 that is 6 commits after tag 1.2.3-4.5.pre, git would
  /// return '1.2.3-4.5.pre-6-gabc123').
  static GitTagVersion parseVersion(String version) {
    final versionPattern = RegExp(
      r'^(\d+)\.(\d+)\.(\d+)(-\d+\.\d+\.pre)?(?:[-\.](\d+)(?:-g([a-f0-9]+))?)?$',
    );
    final Match? match = versionPattern.firstMatch(version.trim());
    if (match == null) {
      return const GitTagVersion.unknown();
    }

    final List<String?> matchGroups = match.groups(<int>[1, 2, 3, 4, 5, 6]);
    final int? x = matchGroups[0] == null ? null : int.tryParse(matchGroups[0]!);
    final int? y = matchGroups[1] == null ? null : int.tryParse(matchGroups[1]!);
    final int? z = matchGroups[2] == null ? null : int.tryParse(matchGroups[2]!);
    final String? devString = matchGroups[3];
    int? devVersion, devPatch;
    if (devString != null) {
      final Match? devMatch = RegExp(r'^-(\d+)\.(\d+)\.pre$').firstMatch(devString);
      final List<String?>? devGroups = devMatch?.groups(<int>[1, 2]);
      devVersion = devGroups?[0] == null ? null : int.tryParse(devGroups![0]!);
      devPatch = devGroups?[1] == null ? null : int.tryParse(devGroups![1]!);
    }
    // count of commits past last tagged version
    final int? commits = matchGroups[4] == null ? 0 : int.tryParse(matchGroups[4]!);
    final String hash = matchGroups[5] ?? '';

    return GitTagVersion(
      x: x,
      y: y,
      z: z,
      devVersion: devVersion,
      devPatch: devPatch,
      commits: commits,
      hash: hash,
      gitTag: '$x.$y.$z${devString ?? ''}', // e.g. 1.2.3-4.5.pre
    );
  }

  @visibleForTesting
  static GitTagVersion parse(String version) {
    GitTagVersion gitTagVersion;

    gitTagVersion = parseVersion(version);
    if (gitTagVersion != const GitTagVersion.unknown()) {
      return gitTagVersion;
    }
    globals.printTrace('Could not interpret results of "git describe": $version');
    return const GitTagVersion.unknown();
  }

  String frameworkVersionFor(String revision) {
    if (x == null || y == null || z == null || !revision.startsWith(hash)) {
      return kUnknownFrameworkVersion;
    }
    if (commits == 0) {
      return gitTag;
    }
    if (hotfix != null) {
      // This is an unexpected state where untagged commits exist past a hotfix
      return '$x.$y.$z+hotfix.${hotfix! + 1}.pre-$commits';
    }
    if (devPatch != null && devVersion != null) {
      // The next tag that will contain this commit will be the next candidate
      // branch, which will increment the devVersion.
      return '$x.$y.0-${devVersion! + 1}.0.pre-$commits';
    }
    return '$x.$y.${z! + 1}-0.0.pre-$commits';
  }
}

enum VersionCheckResult {
  /// Unable to check whether a new version is available, possibly due to
  /// a connectivity issue.
  unknown,

  /// The current version is up to date.
  versionIsCurrent,

  /// A newer version is available.
  newVersionAvailable,
}

/// Determine whether or not the provided [version] is "fresh" and notify the user if appropriate.
///
/// To initiate the validation check, call [run].
///
/// We do not want to check with the upstream git remote for newer commits on
/// every tool invocation, as this would significantly slow down running tool
/// commands. Thus, the tool writes to the [VersionCheckStamp] every time that
/// it actually has fetched commits from upstream, and this validator only
/// checks again if it has been more than [checkAgeConsideredUpToDate] since the
/// last fetch.
///
/// We do not want to notify users with "reasonably" fresh versions about new
/// releases. The method [versionAgeConsideredUpToDate] defines a different
/// duration of freshness for each channel. If [localFrameworkCommitDate] is
/// newer than this duration, then we do not show the warning.
///
/// We do not want to annoy users who intentionally disregard the warning and
/// choose not to upgrade. Thus, we only show the message if it has been more
/// than [maxTimeSinceLastWarning] since the last time the user saw the warning.
class VersionFreshnessValidator {
  VersionFreshnessValidator({
    required this.version,
    required this.localFrameworkCommitDate,
    required this.clock,
    required this.cache,
    required this.logger,
    this.latestFlutterCommitDate,
    this.pauseTime = Duration.zero,
  });

  final FlutterVersion version;
  final DateTime localFrameworkCommitDate;
  final SystemClock clock;
  final Cache cache;
  final Logger logger;
  final Duration pauseTime;
  final DateTime? latestFlutterCommitDate;

  late final DateTime now = clock.now();
  late final Duration frameworkAge = now.difference(localFrameworkCommitDate);

  /// The amount of time we wait before pinging the server to check for the
  /// availability of a newer version of Flutter.
  @visibleForTesting
  static const checkAgeConsideredUpToDate = Duration(days: 3);

  /// The amount of time we wait between issuing a warning.
  ///
  /// This is to avoid annoying users who are unable to upgrade right away.
  @visibleForTesting
  static const maxTimeSinceLastWarning = Duration(days: 1);

  /// The amount of time we pause for to let the user read the message about
  /// outdated Flutter installation.
  ///
  /// This can be customized in tests to speed them up.
  @visibleForTesting
  static Duration timeToPauseToLetUserReadTheMessage = const Duration(seconds: 2);

  // We show a warning if either we know there is a new remote version, or we
  // couldn't tell but the local version is outdated.
  @visibleForTesting
  bool canShowWarning(VersionCheckResult remoteVersionStatus) {
    final bool installationSeemsOutdated =
        frameworkAge > versionAgeConsideredUpToDate(version.channel);
    if (remoteVersionStatus == VersionCheckResult.newVersionAvailable) {
      return true;
    }
    if (!installationSeemsOutdated) {
      return false;
    }
    return remoteVersionStatus == VersionCheckResult.unknown;
  }

  /// We warn the user if the age of their Flutter installation is greater than
  /// this duration. The durations are slightly longer than the expected release
  /// cadence for each channel, to give the user a grace period before they get
  /// notified.
  ///
  /// For example, for the beta channel, this is set to eight weeks because
  /// beta releases happen approximately every month.
  @visibleForTesting
  static Duration versionAgeConsideredUpToDate(String channel) {
    return switch (channel) {
      'stable' => const Duration(days: 365 ~/ 2), // Six months
      'beta' => const Duration(days: 7 * 8), // Eight weeks
      _ => const Duration(days: 7 * 3), // Three weeks
    };
  }

  /// Execute validations and print warning to [logger] if necessary.
  Future<void> run() async {
    // Get whether there's a newer version on the remote. This only goes
    // to the server if we haven't checked recently so won't happen on every
    // command.
    final VersionCheckResult remoteVersionStatus;

    if (latestFlutterCommitDate == null) {
      remoteVersionStatus = VersionCheckResult.unknown;
    } else {
      if (latestFlutterCommitDate!.isAfter(localFrameworkCommitDate)) {
        remoteVersionStatus = VersionCheckResult.newVersionAvailable;
      } else {
        remoteVersionStatus = VersionCheckResult.versionIsCurrent;
      }
    }

    // Do not load the stamp before the above server check as it may modify the stamp file.
    final VersionCheckStamp stamp = await VersionCheckStamp.load(cache, logger);
    final DateTime lastTimeWarningWasPrinted =
        stamp.lastTimeWarningWasPrinted ?? clock.ago(maxTimeSinceLastWarning * 2);
    final bool beenAWhileSinceWarningWasPrinted =
        now.difference(lastTimeWarningWasPrinted) > maxTimeSinceLastWarning;
    if (!beenAWhileSinceWarningWasPrinted) {
      return;
    }

    final bool canShowWarningResult = canShowWarning(remoteVersionStatus);

    if (!canShowWarningResult) {
      return;
    }

    // By this point, we should show the update message
    final String updateMessage;
    switch (remoteVersionStatus) {
      case VersionCheckResult.newVersionAvailable:
        updateMessage = _newVersionAvailableMessage;
      case VersionCheckResult.versionIsCurrent:
      case VersionCheckResult.unknown:
        updateMessage = versionOutOfDateMessage(frameworkAge);
    }

    logger.printBox(updateMessage);
    await Future.wait<void>(<Future<void>>[
      stamp.store(newTimeWarningWasPrinted: now, cache: cache),
      Future<void>.delayed(pauseTime),
    ]);
  }
}

@visibleForTesting
String versionOutOfDateMessage(Duration frameworkAge) {
  return '''
WARNING: your installation of Flutter is ${frameworkAge.inDays} days old.

To update to the latest version, run "flutter upgrade".''';
}

const _newVersionAvailableMessage = '''
A new version of Flutter is available!

To update to the latest version, run "flutter upgrade".''';

/// Data class for parsing engine_stamp.json.
@visibleForTesting
final class FlutterEngineStampFromFile {
  FlutterEngineStampFromFile._({
    required this.buildDate,
    required this.gitRevision,
    required this.gitRevisionDate,
    required this.contentHash,
  });

  /// General time when the engine artifacts were built.
  final DateTime buildDate;

  /// The git commit sha for these engine artifacts.
  final String gitRevision;

  /// The date of the [gitRevision] commit.
  final DateTime gitRevisionDate;

  /// The content-aware hash for this build.
  ///
  /// This hash helps uniquely identify engine changes and reduce artifact builds.
  final String contentHash;

  /// Attempt to parse [jsonFile] for `engine_stamp.json` values.
  static FlutterEngineStampFromFile? tryParseFromFile(File jsonFile) {
    final Map<String, Object?> data;
    try {
      data = json.decode(jsonFile.readAsStringSync()) as Map<String, Object?>;

      if (data case {
        'build_time_ms': final int buildTimeMs,
        'git_revision': final String gitRevision,
        'git_revision_date': final String gitRevisionDate,
        'content_hash': final String contentHash,
      }) {
        return FlutterEngineStampFromFile._(
          buildDate: DateTime.fromMillisecondsSinceEpoch(buildTimeMs),
          gitRevision: gitRevision,
          gitRevisionDate: DateTime.parse(gitRevisionDate),
          contentHash: contentHash,
        );
      }
      // ignore: avoid_catches_without_on_clauses
    } catch (_) {
      return null;
    }
    return null;
  }
}

bool _isStandardRemote(String remote) {
  final String sanitized = VersionUpstreamValidator.stripDotGit(remote);

  // Whitelist custom enterprise mirror or fork if specified by environment variable
  final String? customGitUrl = globals.platform.environment['FLUTTER_GIT_URL'];
  if (customGitUrl != null && VersionUpstreamValidator.stripDotGit(customGitUrl) == sanitized) {
    return true;
  }
  for (final standard in const <String>[
    'https://github.com/flutter/flutter.git',
    'git@github.com:flutter/flutter.git',
    'ssh://git@github.com/flutter/flutter.git',
  ]) {
    if (VersionUpstreamValidator.stripDotGit(standard) == sanitized) {
      return true;
    }
  }
  return false;
}
