package sdsi;

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

/**
 * An alpha-ordering comparator. I guess it's supposed to use
 * ascii order; SPKI docs are vague.
 */
class RCAlpha
	extends RangeComparator {
	RCAlpha(SexpString operator, SexpString limit)
		throws SexpParseException {
		super(operator, limit);
	}

	boolean includes(SexpString sexpString) {
		try {
			// uses SexpString.compareTo(), which may compare display hint
			// info -- could be a problem if tags are allowed to have
			// display hints that are supposed to be operationally invisible.
			int order = limit.compareTo(sexpString);
			if (order==0 && acceptEquality()) {
				return true;
			}
			return wantGreater()
				? (order<0)
				: (order>0);
		} catch (SexpException ex) {
			throw new RuntimeException(ex.toString());
		}
	}

	RangeComparator intersect(RangeComparator otherRC) {
		if (otherRC instanceof RCAny) {
			return this;
		}
		if (!(otherRC instanceof RCAlpha)) {
			// can't mix comparison formulas
			throw new RuntimeException("Incompatible comparators");
		}
		if (otherRC.wantGreater()!=wantGreater()) {
			throw new RuntimeException("Incompatible comparators");
		}
		if (includes(otherRC.getLimit())) {
			// we are at least as inclusive as the other guy --
			// either his limit is more restrictive than ours,
			// or it's the same, but he uses a gt (lt) test and
			// we accept equality (ge/le).
			return otherRC;
		}
		// then either otherRC.includes(limit), or we both have the
		// same limit and don't accept equality. Let's assert this,
		// just to be sure.
		Assert.assert(otherRC.includes(getLimit())
			|| (getLimit().equals(otherRC.getLimit())
				&& !acceptEquality()
				&& !otherRC.acceptEquality()
				)
			);
		return this;
	}
}
