// 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.

/// Possible string formats that `flutter --version` can return.
enum VersionType {
  /// A stable flutter release.
  ///
  /// Example: '1.2.3'
  stable,

  /// A pre-stable flutter release.
  ///
  /// Example: '1.2.3-4.5.pre'
  development,

  /// A master channel flutter version.
  ///
  /// Example: '1.2.3-4.0.pre.10'
  ///
  /// The last number is the number of commits past the last tagged version.
  latest,
}

final Map<VersionType, RegExp> versionPatterns = <VersionType, RegExp>{
  VersionType.stable: RegExp(r'^(\d+)\.(\d+)\.(\d+)$'),
  VersionType.development: RegExp(r'^(\d+)\.(\d+)\.(\d+)-(\d+)\.(\d+)\.pre$'),
  VersionType.latest: RegExp(r'^(\d+)\.(\d+)\.(\d+)-(\d+)\.(\d+)\.pre\.(\d+)$'),
};

class Version {
  Version({
    required this.x,
    required this.y,
    required this.z,
    this.m,
    this.n,
    this.commits,
    required this.type,
  }) {
    switch (type) {
      case VersionType.stable:
        assert(m == null);
        assert(n == null);
        assert(commits == null);
        break;
      case VersionType.development:
        assert(m != null);
        assert(n != null);
        assert(commits == null);
        break;
      case VersionType.latest:
        assert(m != null);
        assert(n != null);
        assert(commits != null);
        break;
    }
  }

  /// Create a new [Version] from a version string.
  ///
  /// It is expected that [versionString] will be generated by
  /// `flutter --version` and match one of `stablePattern`, `developmentPattern`
  /// and `latestPattern`.
  factory Version.fromString(String versionString) {
    assert(versionString != null);

    versionString = versionString.trim();
    // stable tag
    Match? match = versionPatterns[VersionType.stable]!.firstMatch(versionString);
    if (match != null) {
      // parse stable
      final List<int> parts = match
          .groups(<int>[1, 2, 3])
          .map((String? s) => int.parse(s!))
          .toList();
      return Version(
        x: parts[0],
        y: parts[1],
        z: parts[2],
        type: VersionType.stable,
      );
    }
    // development tag
    match = versionPatterns[VersionType.development]!.firstMatch(versionString);
    if (match != null) {
      // parse development
      final List<int> parts =
          match.groups(<int>[1, 2, 3, 4, 5]).map((String? s) => int.parse(s!)).toList();
      return Version(
        x: parts[0],
        y: parts[1],
        z: parts[2],
        m: parts[3],
        n: parts[4],
        type: VersionType.development,
      );
    }
    // latest tag
    match = versionPatterns[VersionType.latest]!.firstMatch(versionString);
    if (match != null) {
      // parse latest
      final List<int> parts = match.groups(
        <int>[1, 2, 3, 4, 5, 6],
      ).map(
        (String? s) => int.parse(s!),
      ).toList();
      return Version(
        x: parts[0],
        y: parts[1],
        z: parts[2],
        m: parts[3],
        n: parts[4],
        commits: parts[5],
        type: VersionType.latest,
      );
    }
    throw Exception('${versionString.trim()} cannot be parsed');
  }

  // Returns a new version with the given [increment] part incremented.
  // NOTE new version must be of same type as previousVersion.
  factory Version.increment(
    Version previousVersion,
    String increment, {
    VersionType? nextVersionType,
  }) {
    final int nextX = previousVersion.x;
    int nextY = previousVersion.y;
    int nextZ = previousVersion.z;
    int? nextM = previousVersion.m;
    int? nextN = previousVersion.n;
    if (nextVersionType == null) {
      if (previousVersion.type == VersionType.latest) {
        nextVersionType = VersionType.development;
      } else {
        nextVersionType = previousVersion.type;
      }
    }

    switch (increment) {
      case 'x':
        // This was probably a mistake.
        throw Exception('Incrementing x is not supported by this tool.');
      case 'y':
        // Dev release following a beta release.
        nextY += 1;
        nextZ = 0;
        if (previousVersion.type != VersionType.stable) {
          nextM = 0;
          nextN = 0;
        }
        break;
      case 'z':
        // Hotfix to stable release.
        assert(previousVersion.type == VersionType.stable);
        nextZ += 1;
        break;
      case 'm':
        // Regular dev release.
        assert(previousVersion.type == VersionType.development);
        nextM = nextM! + 1;
        nextN = 0;
        break;
      case 'n':
        // Hotfix to internal roll.
        nextN = nextN! + 1;
        break;
      default:
        throw Exception('Unknown increment level $increment.');
    }
    return Version(
      x: nextX,
      y: nextY,
      z: nextZ,
      m: nextM,
      n: nextN,
      type: nextVersionType,
    );
  }

  /// Major version.
  final int x;

  /// Zero-indexed count of beta releases after a major release.
  final int y;

  /// Number of hotfix releases after a stable release.
  final int z;

  /// Zero-indexed count of dev releases after a beta release.
  final int? m;

  /// Number of hotfixes required to make a dev release.
  final int? n;

  /// Number of commits past last tagged dev release.
  final int? commits;

  final VersionType type;

  @override
  String toString() {
    switch (type) {
      case VersionType.stable:
        return '$x.$y.$z';
      case VersionType.development:
        return '$x.$y.$z-$m.$n.pre';
      case VersionType.latest:
        return '$x.$y.$z-$m.$n.pre.$commits';
    }
  }
}
