import { DomainException } from '../../shared/exceptions/domain.exception';

/**
 * 版本名称值对象
 * 格式: major.minor.patch 或 major.minor.patch.build (e.g., 1.0.0, 1.0.0.4)
 */
export class VersionName {
  private readonly _value: string;
  private readonly _major: number;
  private readonly _minor: number;
  private readonly _patch: number;
  private readonly _build?: number;

  private constructor(value: string, major: number, minor: number, patch: number, build?: number) {
    this._value = value;
    this._major = major;
    this._minor = minor;
    this._patch = patch;
    this._build = build;
  }

  get value(): string {
    return this._value;
  }

  get major(): number {
    return this._major;
  }

  get minor(): number {
    return this._minor;
  }

  get patch(): number {
    return this._patch;
  }

  get build(): number | undefined {
    return this._build;
  }

  static create(value: string): VersionName {
    if (!value || value.trim() === '') {
      throw new DomainException('VersionName cannot be empty');
    }

    const trimmed = value.trim();
    // 支持 x.y.z 或 x.y.z.w 格式
    const versionPattern = /^(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?$/;
    const match = trimmed.match(versionPattern);

    if (!match) {
      throw new DomainException('VersionName must follow semantic versioning format (e.g., 1.0.0 or 1.0.0.4)');
    }

    const major = parseInt(match[1], 10);
    const minor = parseInt(match[2], 10);
    const patch = parseInt(match[3], 10);
    const build = match[4] ? parseInt(match[4], 10) : undefined;

    return new VersionName(trimmed, major, minor, patch, build);
  }

  equals(other: VersionName): boolean {
    return this._value === other._value;
  }

  toString(): string {
    return this._value;
  }
}
