/**
 * Copyright © 2024 Nevis Security AG. All rights reserved.
 */

/**
 * Represents a generic version with major, minor, patch and buildNumber fields.
 */
export abstract class Version {
	/**
	 * The major field of the version, such as 1 in version 1.5.3.4.
	 */
	abstract major: number;

	/**
	 * The minor field of the version, such as 5 in version 1.5.3.4.
	 */
	abstract minor: number;

	/**
	 * The patch field of the version, such as 3 in version 1.5.3.4.
	 */
	abstract patch: number;

	/**
	 * The build number field of the version, such as 4 in version 1.5.3.4.
	 */
	abstract buildNumber: number;

	/**
	 * Default constructor for {@link Version}.
	 *
	 * @param major major field of the version.
	 * @param minor minor field of the version.
	 * @param patch patch field of the version.
	 * @param buildNumber build number field of the version.
	 * @returns a {@link Version} instance.
	 */
	static create(major: number, minor: number, patch: number, buildNumber: number): Version {
		return new VersionImpl(major, minor, patch, buildNumber);
	}

	/**
	 * Alternate constructor that creates a {@link Version} from a json.
	 *
	 * @param json contains the source for instance creation.
	 * @returns a {@link Version} instance.
	 */
	static fromJson(json: any): Version {
		return VersionImpl.fromJson(json);
	}
}

export class VersionImpl extends Version {
	major: number;
	minor: number;
	patch: number;
	buildNumber: number;

	constructor(major: number, minor: number, patch: number, buildNumber: number) {
		super();
		this.major = major;
		this.minor = minor;
		this.patch = patch;
		this.buildNumber = buildNumber;
	}

	static fromJson(json: any): VersionImpl {
		if (
			json.major === undefined ||
			json.minor === undefined ||
			json.patch === undefined ||
			json.buildNumber === undefined
		) {
			throw new Error(
				'Unknown Version; Some parts of the version is not present in json: ',
				json
			);
		}
		return new VersionImpl(json.major, json.minor, json.patch, json.buildNumber);
	}
}
