package proof;

import sdsi.*;
import sdsi.sexp.*;
import Tools.*;

import java.security.*;
import java.util.*;

/**
 * This proof proves that a principal speaks for itself ({@tex $A=A$).
 * It's kind of silly to reify this as an explicit object, but it
 * avoids putting potentially-confusing special-case code in the
 * proof verifier.
 */
public class TrivialProof
	extends Proof {

	SDSIPrincipal thePrincipal;

	static final String LABEL = "trivial";

	public TrivialProof(SexpList list)
		throws SexpParseException {
		if (!(list.getType().equals(Proof.LABEL)
				&& ((SexpString) list.elementAt(1)).stringContent()
					.equals(TrivialProof.LABEL)
				&& list.size()==3
				&& (list.elementAt(2) instanceof SexpList)
			)) {
			throw new SexpParseException("incorrectly formatted trivial proof");
		}
		
		thePrincipal = (SDSIPrincipal) KeyTools.parseSexp(list.elementAt(2));

		srep = list;
	}

	public TrivialProof(SDSIPrincipal thePrincipal) {
		this.thePrincipal = thePrincipal;

		Sexp[] sexpary = new Sexp[3];
		sexpary[0] = new SexpString("proof");
		sexpary[1] = new SexpString(TrivialProof.LABEL);
		sexpary[2] = thePrincipal.getSrep();
		srep = new SexpList(sexpary);
	}

	public SDSIPrincipal getIssuer() {
		return thePrincipal;
	}

	public Subject getSubject() {
		return thePrincipal;
	}

	/**
	 * verify that the proof steps are indeed valid, and that they
	 * combine as advertised to show the claimed result
	 */
	protected void directVerify()
		throws InvalidProofException {
		// Hey, if you're happy with thePrincipal, I am.
		return;
	}

	void preorder(List addToMe, int what) {
		// if this node had its own issuer, we'd insert it here.
		switch (what) {
			case Proof.ISSUERS:
				addToMe.add(getIssuer());
				break;
			case Proof.CERTIFICATES:
				break;
			case Proof.PROOFS:
				addToMe.add(this);
				break;
			default:
				throw new RuntimeException("undefined what.");
		}
	}

	public Tag getTag() {
		return Tag.getTagStar();
	}

// Bonehead: I'm a SDSIObject; these are already implemented well.
//	public boolean equals(Object o) {
//		if (!(o instanceof TrivialProof)) {
//			return false;
//		}
//		TrivialProof tp = (TrivialProof) o;
//		return thePrincipal.equals(tp.thePrincipal);
//	}
//
//	public int hashCode() {
//		return thePrincipal.hashCode();
//	}
}
