// 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';

@immutable
class Version implements Comparable<Version> {
  /// Creates a new [Version] object.
  factory Version(int? major, int? minor, int? patch, {String? text}) {
    if (text == null) {
      text = major == null ? '0' : '$major';
      if (minor != null) {
        text = '$text.$minor';
      }
      if (patch != null) {
        text = '$text.$patch';
      }
    }

    return Version._(major ?? 0, minor ?? 0, patch ?? 0, text);
  }

  Version._(this.major, this.minor, this.patch, this._text) {
    if (major < 0) {
      throw ArgumentError('Major version must be non-negative.');
    }
    if (minor < 0) {
      throw ArgumentError('Minor version must be non-negative.');
    }
    if (patch < 0) {
      throw ArgumentError('Patch version must be non-negative.');
    }
  }

  /// Creates a new [Version] by parsing [text].
  static Version? parse(String? text) {
    final Match? match = versionPattern.firstMatch(text ?? '');
    if (match == null) {
      return null;
    }

    try {
      final int major = int.parse(match[1] ?? '0');
      final int minor = int.parse(match[3] ?? '0');
      final int patch = int.parse(match[5] ?? '0');
      return Version._(major, minor, patch, text ?? '');
    } on FormatException {
      return null;
    }
  }

  /// Returns the primary version out of a list of candidates.
  ///
  /// This is the highest-numbered stable version.
  static Version? primary(List<Version> versions) {
    Version? primary;
    for (final Version version in versions) {
      if (primary == null || (version > primary)) {
        primary = version;
      }
    }
    return primary;
  }


  static Version get unknown => Version(0, 0, 0, text: 'unknown');

  /// The major version number: "1" in "1.2.3".
  final int major;

  /// The minor version number: "2" in "1.2.3".
  final int minor;

  /// The patch version number: "3" in "1.2.3".
  final int patch;

  /// The original string representation of the version number.
  ///
  /// This preserves textual artifacts like leading zeros that may be left out
  /// of the parsed version.
  final String _text;

  static final RegExp versionPattern =
      RegExp(r'^(\d+)(\.(\d+)(\.(\d+))?)?');

  /// Two [Version]s are equal if their version numbers are. The version text
  /// is ignored.
  @override
  bool operator ==(Object other) {
    return other is Version
        && other.major == major
        && other.minor == minor
        && other.patch == patch;
  }

  @override
  int get hashCode => major ^ minor ^ patch;

  bool operator <(Version other) => compareTo(other) < 0;
  bool operator >(Version other) => compareTo(other) > 0;
  bool operator <=(Version other) => compareTo(other) <= 0;
  bool operator >=(Version other) => compareTo(other) >= 0;

  @override
  int compareTo(Version other) {
    if (major != other.major) {
      return major.compareTo(other.major);
    }
    if (minor != other.minor) {
      return minor.compareTo(other.minor);
    }
    return patch.compareTo(other.patch);
  }

  @override
  String toString() => _text;
}
