import semver from 'semver';

export interface Version {
  check(version: any): boolean;

  valid(version: string): string;

  satisfies(version: string, range: string): boolean;

  gt(v1: string, v2: string): boolean;
}

export class SemverVersion implements Version {
  private validVersions = ['latest', 'beta'];

  public check(version: any): boolean {
    if (this.validVersions.includes(version)) {
      return true;
    }
    return semver.valid(version) !== null;
  }

  public checkRange(version: any): boolean {
    if (this.validVersions.includes(version)) {
      return true;
    }
    return semver.validRange(version) !== null;
  }

  public isRange(version: any): boolean {
    if (this.validVersions.includes(version)) {
      return true;
    }
    return !this.check(version) && this.checkRange(version);
  }

  public valid(version: string): string {
    if (this.validVersions.includes(version)) {
      return version;
    }
    const v = semver.valid(version);
    if (v) {
      return 'v' + v;
    }
    return version;
  }

  public toFull(version: string): string {
    if (this.validVersions.includes(version)) {
      return version;
    }
    const fullVersion = version.toLowerCase();
    if (!version.startsWith('v')) {
      return 'v' + version;
    }
    return fullVersion;
  }

  public satisfies(version: string, range: string): boolean {
    return semver.satisfies(this.valid(version), range);
  }

  public gt(v1: string, v2: string): boolean {
    return semver.gt(this.valid(v1), this.valid(v2));
  }
}

export default new SemverVersion();
