/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.jena.permissions.model;

import java.util.Set;

import org.apache.jena.permissions.MockSecurityEvaluator;
import org.apache.jena.permissions.SecurityEvaluator;
import org.apache.jena.permissions.SecurityEvaluatorParameters;
import org.apache.jena.permissions.SecurityEvaluator.Action;
import org.apache.jena.permissions.model.SecuredAlt;
import org.apache.jena.permissions.model.SecuredBag;
import org.apache.jena.permissions.model.SecuredSeq;
import org.apache.jena.permissions.model.impl.SecuredSeqImpl;
import org.apache.jena.rdf.model.Alt;
import org.apache.jena.rdf.model.Bag;
import org.apache.jena.rdf.model.ResourceFactory;
import org.apache.jena.rdf.model.Seq;
import org.apache.jena.shared.AccessDeniedException;
import org.apache.jena.shared.ReadDeniedException;
import org.apache.jena.shared.UpdateDeniedException;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(value = SecurityEvaluatorParameters.class)
public class SecuredSeqTest extends SecuredContainerTest {
	private Seq seq;

	public SecuredSeqTest(final MockSecurityEvaluator securityEvaluator) {
		super(securityEvaluator);
		// TODO Auto-generated constructor stub
	}

	private SecuredSeq getSecuredSeq() {
		return (SecuredSeq) getSecuredRDFNode();
	}

	@Override
	@Before
	public void setup() {
		super.setup();
		seq = baseModel.getSeq("http://example.com/testContainer");
		setSecuredRDFNode(SecuredSeqImpl.getInstance(securedModel, seq), seq);
	}

	@Override
	@Test
	public void testAdd() {
		final Set<Action> perms = SecurityEvaluator.Util.asSet(new Action[] {
				Action.Update, Action.Create });
		try {
			getSecuredSeq().add(2, true);
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown AccessDeniedException Exception");
			}
		} catch (final AccessDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown AccessDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().add(2, 'c');
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown AccessDeniedException Exception");
			}
		} catch (final AccessDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown AccessDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().add(2, 3.14d);
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown AccessDeniedException Exception");
			}
		} catch (final AccessDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown AccessDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().add(2, 3.14F);
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown AccessDeniedException Exception");
			}
		} catch (final AccessDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown AccessDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().add(2, 3L);
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown AccessDeniedException Exception");
			}
		} catch (final AccessDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown AccessDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			final Object o = Integer.MAX_VALUE;
			getSecuredSeq().add(2, o);
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown AccessDeniedException Exception");
			}
		} catch (final AccessDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown AccessDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().add(2, ResourceFactory.createResource());
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown AccessDeniedException Exception");
			}
		} catch (final AccessDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown AccessDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().add(2, "Waa hoo");
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown AccessDeniedException Exception");
			}
		} catch (final AccessDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown AccessDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().add(2, "dos", "es");
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown AccessDeniedException Exception");
			}
		} catch (final AccessDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown AccessDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}
	}

	@Test
	public void testGetAlt() {
		try {
			final Alt a = getSecuredSeq().getAlt(1);
			Assert.assertTrue("Should be a secured Alt",
					a instanceof SecuredAlt);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}
	}

	@Test
	public void testGetBag() {
		try {
			final Bag a = getSecuredSeq().getBag(1);
			Assert.assertTrue("Should be a secured Bag",
					a instanceof SecuredBag);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

	}

	@Test
	public void testGetBoolean() {
		seq.add(2, true);
		try {
			getSecuredSeq().getBoolean(2);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

	}

	@Test
	public void testGetByte() {
		seq.add(2, Byte.MAX_VALUE);
		try {
			getSecuredSeq().getByte(2);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

	}

	@Test
	public void testGetChar() {
		seq.add(2, 'c');
		try {
			getSecuredSeq().getChar(2);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

	}

	@Test
	public void testGetDouble() {
		seq.add(2, 3.14D);
		try {
			getSecuredSeq().getDouble(2);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

	}

	@Test
	public void testGetFloat() {
		seq.add(2, 3.14F);
		try {
			getSecuredSeq().getFloat(2);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

	}

	@Test
	public void testGetInt() {
		seq.add(2, 2);
		try {
			getSecuredSeq().getInt(2);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

	}

	@Test
	public void testGetLanguage() {
		seq.add(2, "foo");
		try {
			getSecuredSeq().getLanguage(2);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

	}

	@Test
	public void testGetLiteral() {
		seq.add(2, "foo");
		try {
			getSecuredSeq().getLiteral(2);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

	}

	@Test
	public void testGetLong() {
		seq.add(2, 2L);
		try {
			getSecuredSeq().getLong(2);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

	}

	@Test
	public void testGetObject() {
		final Object o = Integer.MAX_VALUE;
		seq.add(2, o);
		try {
			getSecuredSeq().getObject(2);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

	}

	@Test
	public void testGetResource() {
		seq.add(2, ResourceFactory.createResource());
		try {
			getSecuredSeq().getResource(2);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

	}

	@Test
	public void testGetSeq() {
		seq.add(2, 'c');
		try {
			getSecuredSeq().getSeq(2);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

	}

	@Test
	public void testGetShort() {
		seq.add(2, Short.MAX_VALUE);
		try {
			getSecuredSeq().getShort(2);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

	}

	@Test
	public void testGetString() {
		seq.add(2, "Waaa hoo");
		try {
			getSecuredSeq().getString(2);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

	}

	@Test
	public void testIndexOf() {
		try {
			getSecuredSeq().indexOf(true);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().indexOf('c');
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().indexOf(3.14D);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().indexOf(3.14F);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().indexOf(3L);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			final Object o = Integer.MAX_VALUE;
			getSecuredSeq().indexOf(o);
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {

			getSecuredSeq()
					.indexOf(
							ResourceFactory
									.createResource("http://example.com/exampleResource"));
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().indexOf("waaa hooo");
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().indexOf("dos", "es");
			if (!securityEvaluator.evaluate(Action.Read)) {
				Assert.fail("Should have thrown ReadDeniedException Exception");
			}
		} catch (final ReadDeniedException e) {
			if (securityEvaluator.evaluate(Action.Read)) {
				Assert.fail(String
						.format("Should not have thrown ReadDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

	}

	@Override
	@Test
	public void testRemove() {
		final Set<Action> perms = SecurityEvaluator.Util.asSet(new Action[] {
				Action.Update, Action.Delete });
		try {
			getSecuredSeq().remove(1);
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown AccessDeniedException Exception");
			}
		} catch (final AccessDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown AccessDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}
	}

	@Test
	public void testSet() {
		final Set<Action> perms = SecurityEvaluator.Util
				.asSet(new Action[] { Action.Update });
		try {
			getSecuredSeq().set(1, true);
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown UpdateDeniedException Exception");
			}
		} catch (final UpdateDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown UpdateDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().set(1, 'c');
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown UpdateDeniedException Exception");
			}
		} catch (final UpdateDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown UpdateDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().set(1, 3.14d);
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown UpdateDeniedException Exception");
			}
		} catch (final UpdateDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown UpdateDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().set(1, 3.14F);
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown UpdateDeniedException Exception");
			}
		} catch (final UpdateDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown UpdateDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().set(1, 3L);
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown UpdateDeniedException Exception");
			}
		} catch (final UpdateDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown UpdateDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			final Object o = Integer.MAX_VALUE;
			getSecuredSeq().set(1, o);
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown UpdateDeniedException Exception");
			}
		} catch (final UpdateDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown UpdateDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().set(1, ResourceFactory.createResource());
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown UpdateDeniedException Exception");
			}
		} catch (final UpdateDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown UpdateDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().set(1, "Waa hoo");
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown UpdateDeniedException Exception");
			}
		} catch (final UpdateDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown UpdateDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}

		try {
			getSecuredSeq().set(1, "dos", "es");
			if (!securityEvaluator.evaluate(perms)) {
				Assert.fail("Should have thrown UpdateDeniedException Exception");
			}
		} catch (final UpdateDeniedException e) {
			if (securityEvaluator.evaluate(perms)) {
				Assert.fail(String
						.format("Should not have thrown UpdateDeniedException Exception: %s - %s",
								e, e.getTriple()));
			}
		}
	}

}
