// 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 './globals.dart' show ConductorException;

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

  /// A master channel flutter version from git describe.
  ///
  /// Example: '1.2.3-4.0.pre-10-gabc123'.
  gitDescribe,
}

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+)$'),
  VersionType.gitDescribe: RegExp(r'^(\d+)\.(\d+)\.(\d+)-(\d+)\.(\d+)\.pre-(\d+)-g[a-f0-9]+$'),
};

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;
      case VersionType.gitDescribe:
        throw ConductorException(
          'VersionType.gitDescribe not supported! Use VersionType.latest instead.',
        );
    }
  }

  /// 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,
      );
    }
    match = versionPatterns[VersionType.gitDescribe]!.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 || previousVersion.type == VersionType.gitDescribe) {
        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':
        assert(false, "Do not increment 'm' via Version.increment, use instead Version.fromCandidateBranch()");
        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,
    );
  }

  factory Version.fromCandidateBranch(String branchName) {
    // Regular dev release.
    final RegExp pattern = RegExp(r'flutter-(\d+)\.(\d+)-candidate.(\d+)');
    final RegExpMatch? match = pattern.firstMatch(branchName);
    late final int x;
    late final int y;
    late final int m;
    try {
      x = int.parse(match!.group(1)!);
      y = int.parse(match.group(2)!);
      m = int.parse(match.group(3)!);
    } on Exception {
      throw ConductorException('branch named $branchName not recognized as a valid candidate branch');
    }

    return Version(
      type: VersionType.development,
      x: x,
      y: y,
      z: 0,
      m: m,
      n: 0,
    );
  }

  /// 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';
      case VersionType.gitDescribe:
        return '$x.$y.$z-$m.$n.pre.$commits';
    }
  }
}
