/*=============================================================================#
 # Copyright (c) 2008, 2019 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.rj.server;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Objects;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.rj.data.RJIO;
import org.eclipse.statet.rj.data.RJIOExternalizable;


@NonNullByDefault
public final class RjsStatus implements RjsComObject, Externalizable, RJIOExternalizable {
	
	
	public static final int OK=               0x0;
	public static final int INFO=             0x1;
	public static final int WARNING=          0x2;
	public static final int ERROR=            0x4;
	public static final int CANCEL=           0x8;
	
	
	public static final RjsStatus OK_STATUS= new RjsStatus(OK, 0);
	
	public static final RjsStatus CANCEL_STATUS= new RjsStatus(CANCEL, 0);
	
	
	private int severity;
	private int code;
	private @Nullable String text;
	
	
	/**
	 * Constructor to create a status object without a message
	 */
	public RjsStatus(final int severity, final int code) {
		this.severity= severity;
		this.code= code;
		this.text= null;
	}
	
	/**
	 * Constructor to create a status object with a message
	 */
	public RjsStatus(final int severity, final int code, final @Nullable String s) {
		this.severity= severity;
		this.code= code;
		this.text= (s != null && s.length() > 0) ? s : null;
	}
	
	/**
	 * Constructor for automatic deserialization
	 */
	public RjsStatus() {
	}
	
	/**
	 * Constructor for deserialization
	 */
	public RjsStatus(final ObjectInput in) throws IOException {
		readExternal(in);
	}
	
	public RjsStatus(final RJIO io) throws IOException {
		if (io.readBoolean()) {
			this.severity= io.readByte();
			this.code= io.readInt();
			this.text= io.readString();
		}
		else {
			this.severity= io.readByte();
			this.code= io.readInt();
			this.text= null;
		}
	}
	
	@Override
	public void writeExternal(final RJIO io) throws IOException {
		if (this.text != null) {
			io.writeBoolean(true);
			io.writeByte(this.severity);
			io.writeInt(this.code);
			io.writeString(this.text);
		}
		else {
			io.writeBoolean(false);
			io.writeByte(this.severity);
			io.writeInt(this.code);
		}
	}
	
	@Override
	public void readExternal(final ObjectInput in) throws IOException {
		if (in.readBoolean()) {
			this.severity= in.readByte();
			this.code= in.readInt();
			this.text= in.readUTF();
		}
		else {
			this.severity= in.readByte();
			this.code= in.readInt();
			this.text= null;
		}
	}
	
	@Override
	public void writeExternal(final ObjectOutput out) throws IOException {
		if (this.text != null) {
			out.writeBoolean(true);
			out.writeByte(this.severity);
			out.writeInt(this.code);
			out.writeUTF(this.text);
		}
		else {
			out.writeBoolean(false);
			out.writeByte(this.severity);
			out.writeInt(this.code);
		}
	}
	
	
	@Override
	public int getComType() {
		return RjsComObject.T_STATUS;
	}
	
	public int getSeverity() {
		return this.severity;
	}
	
	public int getCode() {
		return this.code;
	}
	
	public String getMessage() {
		return (this.text != null) ? this.text : "";
	}
	
	
	@Override
	public int hashCode() {
		return this.severity+this.code;
	}
	
	@Override
	public boolean equals(final @Nullable Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj instanceof RjsStatus) {
			final RjsStatus other= (RjsStatus) obj;
			return (this.code == other.getCode()
					&& this.severity == other.getSeverity()
					&& Objects.equals(this.text, other.text) );
		}
		return false;
	}
	
	
	@Override
	public String toString() {
		final StringBuffer sb= new StringBuffer(100);
		sb.append("RjsStatus (severity=");
		switch (this.severity) {
		case OK:
			sb.append("OK");
			break;
		case INFO:
			sb.append("INFO");
			break;
		case WARNING:
			sb.append("WARNING");
			break;
		case ERROR:
			sb.append("ERROR");
			break;
		case CANCEL:
			sb.append("CANCEL");
			break;
		default:
			sb.append(this.severity);
			break;
		}
		sb.append(", code=0x");
		sb.append(Integer.toHexString(this.code));
		sb.append(")");
		if (this.text != null) {
			sb.append("\n<TEXT>\n");
			sb.append(this.text);
			sb.append("\n</TEXT>");
		}
		else {
			sb.append("\n<TEXT />");
		}
		return sb.toString();
	}
	
}
