package org.eclipse.europa.tools.webgen;

public class Status {
	public enum SType {
		Fail, Success, Information, Unknown
	};

	public enum Pack200Type {
		All, Some, None, Unknown
	};

	public enum SigningType {
		All, Some, None, Unknown
	};

	public static Status unknown = new Status("unable to determine status",
			SType.Unknown);

	public static Status success = new Status("Success", SType.Success, 500);

	public static Status internal_error = new Status("build system error",
			SType.Fail, 10);

	public static Status fail_bad_version_number = new Status(
			"Bad Version Number", SType.Fail, 100);

	public static Status no_matching_features = new Status(
			"No Matching Features", SType.Fail, 200);

	public static Status fail_file_not_found = new Status("File Not Found",
			SType.Fail, 300);

	public static Status feature_not_in_site_xml = new Status(
			"Site.xml Missing Feature", SType.Fail, 400);

	public static Status license_error = new Status(
			"License Error", SType.Fail, 500);

	public static Status packing_corruption = new Status(
			"Pack200 Corruption", SType.Fail, 600);

	public static Status fail = new Status("Fail", SType.Fail, 1000);

	public static Status information = new Status("unknown", SType.Information);

	private String string;

	private int badness;

	private SType stype;

	private Pack200Type ptype = Pack200Type.Unknown;

	private SigningType ntype = SigningType.Unknown;

	public Status(String s, SType t) {
		this.string = s;
		this.badness = 500;
		this.stype = t;
	}

	public Status(String s, SType t, int b) {
		this.string = s;
		this.badness = b;
		this.stype = t;
	}

	public boolean isFail() {
		return this.stype == SType.Fail;
	}

	public Status moreSpecificFail(Status other) {
		if (this.isFail() && other.isFail()) {
			if (this.badness < other.badness)
				return this;
			else
				return other;
		}
		if (this.isFail())
			return this;
		if (other.isFail())
			return other;
		throw new Error("badness 10,000 " + this + " " + other);
	}

	public boolean isInformation() {
		return this.stype == SType.Information;
	}

	public boolean isSuccess() {
		return this.stype == SType.Success;
	}

	public Status combine(Status other) {
		// Status: Fail > Success > Unknown > Information
		// Pack200: NN->N, AA->A, *S->S, AN->S, *U->*
		// Signing: .ditto.

		String rules = "NN->N,NA->S,NS->S,NU->N,AN->S,AA->A,AS->S,AU->A,"
				+ "SN->S,SA->S,SS->S,SU->S,UN->N,UA->A,US->S,UU->U,";
		Pack200Type newptype = combinePack200(other, rules);
		SigningType newntype = combineSigning(other, rules);

		Status newstatus = new Status("unknown", SType.Unknown);
		if (this.isFail() || other.isFail())
			newstatus = moreSpecificFail(other);
		else if (this.isSuccess())
			newstatus = this;
		else if (other.isSuccess())
			newstatus = other;
		else if (this.isInformation())
			newstatus = this;
		else if (other.isInformation())
			newstatus = other;
		else
			newstatus = this;

		newstatus.ntype = newntype;
		newstatus.ptype = newptype;
		return newstatus;
	}

	public Status addPack200Status( Pack200Type p ) {
		Status newstatus = new Status("unknown", SType.Unknown);
		newstatus.ptype = p;
		return this.combine(newstatus);
	}
	public String toString() {
		return this.string;
	}

	private Pack200Type combinePack200(Status other, String combineRules) {
		Pack200Type newptype = Pack200Type.Unknown;
		String tmp = "";
		if (this.ptype == Pack200Type.All)
			tmp += "A";
		if (this.ptype == Pack200Type.Some)
			tmp += "S";
		if (this.ptype == Pack200Type.None)
			tmp += "N";
		if (this.ptype == Pack200Type.Unknown)
			tmp += "U";
		if (other.ptype == Pack200Type.All)
			tmp += "A";
		if (other.ptype == Pack200Type.Some)
			tmp += "S";
		if (other.ptype == Pack200Type.None)
			tmp += "N";
		if (other.ptype == Pack200Type.Unknown)
			tmp += "U";
		tmp += "->";
		int tmp2 = combineRules.indexOf(tmp);
		String tmp3 = combineRules.substring(tmp2 + 4, tmp2 + 5);
		if (tmp3.equals("A"))
			newptype = Pack200Type.All;
		if (tmp3.equals("N"))
			newptype = Pack200Type.None;
		if (tmp3.equals("S"))
			newptype = Pack200Type.Some;
		if (tmp3.equals("U"))
			newptype = Pack200Type.Unknown;
		return newptype;
	}

	private SigningType combineSigning(Status other, String combineRules) {
		SigningType newptype = SigningType.Unknown;
		String tmp = "";
		if (this.ntype == SigningType.All)
			tmp += "A";
		if (this.ntype == SigningType.Some)
			tmp += "S";
		if (this.ntype == SigningType.None)
			tmp += "N";
		if (this.ntype == SigningType.Unknown)
			tmp += "U";
		if (other.ntype == SigningType.All)
			tmp += "A";
		if (other.ntype == SigningType.Some)
			tmp += "S";
		if (other.ntype == SigningType.None)
			tmp += "N";
		tmp += "U";
		tmp += "->";
		int tmp2 = combineRules.indexOf(tmp);
		String tmp3 = combineRules.substring(tmp2 + 4, tmp2 + 5);
		if (tmp3.equals("A"))
			newptype = SigningType.All;
		if (tmp3.equals("N"))
			newptype = SigningType.None;
		if (tmp3.equals("S"))
			newptype = SigningType.Some;
		if (tmp3.equals("U"))
			newptype = SigningType.Unknown;
		return newptype;
	}
}
