/*******************************************************************************
 * Copyright (c) 2009, 2012 SAP AG and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     SAP AG - initial API and implementation
 ******************************************************************************/
package org.eclipse.ocl.examples.impactanalyzer.tests.instanceScope;

import java.util.Collection;

import junit.framework.TestCase;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.ocl.ParserException;
import org.eclipse.ocl.SemanticException;
import org.eclipse.ocl.ecore.LoopExp;
import org.eclipse.ocl.ecore.OCL;
import org.eclipse.ocl.ecore.OCL.Helper;
import org.eclipse.ocl.ecore.OCLExpression;
import org.eclipse.ocl.util.Bag;
import org.junit.Before;
import org.junit.Test;

import company.CompanyFactory;
import company.CompanyPackage;

import data.classes.ClassTypeDefinition;
import data.classes.ClassesFactory;
import data.classes.ClassesPackage;
import data.classes.MethodSignature;
import data.classes.Parameter;
import data.classes.SapClass;


public class QuickOclParseAndEvalTest extends TestCase
{
  private SapClass class1;
  private SapClass class2;
  private Parameter param;
  private ClassTypeDefinition ctd;
  private MethodSignature signature;
  private OCL ocl;
  private Helper oclHelper;

  private void assertInvalid(Object object) {
	  assertEquals(ocl.getEnvironment().getOCLStandardLibrary().getInvalid(), object);
  }

  @Before
  public void setUp()
  {
    class1 = ClassesFactory.eINSTANCE.createSapClass();
    class1.setName("class1");
    class2 = ClassesFactory.eINSTANCE.createSapClass();
    class2.setName("class2");
    signature = ClassesFactory.eINSTANCE.createMethodSignature();
    signature.setName("context");
    param = ClassesFactory.eINSTANCE.createParameter();
    param.setName("p");
    ctd = ClassesFactory.eINSTANCE.createClassTypeDefinition();
    ctd.setClazz(class1);
    param.setOwnedTypeDefinition(ctd);
    signature.setOwner(class2);
    ocl = org.eclipse.ocl.examples.impactanalyzer.util.OCL.newInstance();
    oclHelper = ocl.createOCLHelper();
    oclHelper.setContext(ClassesPackage.eINSTANCE.getParameter());
  }

  /**
   * Check if it is possible to create an expression in context Boolean
   */
  @Test
  public void testParseAndEvaluateOclExpressionInContextBoolean() throws ParserException {
      oclHelper.setContext(EcorePackage.eINSTANCE.getEBoolean());
      {
          OCLExpression expression4 = oclHelper.createQuery("self");
          Object result4 = ocl.evaluate(true, expression4);
          assertTrue((Boolean) result4);
          Object result5 = ocl.evaluate(false, expression4);
          assertFalse((Boolean) result5);
      }
      {
          OCLExpression expression4 = oclHelper.createQuery("not self");
          Object result4 = ocl.evaluate(true, expression4);
          assertFalse((Boolean) result4);
          Object result5 = ocl.evaluate(false, expression4);
          assertTrue((Boolean) result5);
      }
  }

  /**
   * Check if a type name parses as a type literal
   */
  @Test
  public void testParseAndEvaluateOclExpressionWithTypeLiteral() throws ParserException {
      oclHelper.setContext(CompanyPackage.eINSTANCE.getDepartment());
      OCLExpression expression4 = oclHelper.createQuery("company::Division");
      Object result4 = ocl.evaluate(null, expression4);
      assertTrue(result4 instanceof EClass);
      assertEquals(CompanyPackage.eINSTANCE.getDivision(), result4);
      OCLExpression expression5 = oclHelper.createQuery("Division");
      Object result5 = ocl.evaluate(null, expression5);
      assertTrue(result5 instanceof EClass);
      assertEquals(CompanyPackage.eINSTANCE.getDivision(), result5);
  }

  /**
   * Check what happens when ->at(...) argument is out of bounds
   */
  @Test
  public void testParseAndEvaluateOclExpressionWithOutOfBoundsAtArgument() throws ParserException {
      oclHelper.setContext(CompanyPackage.eINSTANCE.getDepartment());
      OCLExpression expression4 = oclHelper.createQuery("Sequence{1..2}->at(3)");
      Object result4 = ocl.evaluate(CompanyFactory.eINSTANCE.createDepartment(), expression4);
      assertInvalid(result4);
  }


/**
   * Check what happens when last value of a range is invalid instead of an Integer. Interestingly, this aborts the whole
   * evaluation and even "bypasses" a trailing oclIsInvalid().
   */
  @Test
  public void testParseAndEvaluateOclExpressionWithInvalidAsLastPartOfRange() throws ParserException {
      oclHelper.setContext(CompanyPackage.eINSTANCE.getDepartment());
      OCLExpression expression4 = oclHelper.createQuery("(Sequence{1..(self.parentDepartment.subDepartment->size())}->select(i | i>0)).oclIsInvalid()");
      Object result4 = ocl.evaluate(CompanyFactory.eINSTANCE.createDepartment(), expression4);
      assertInvalid(result4);
  }

  /**
   * Check if invalid can be passed into an operation as argument
   */
  @Test
  public void testParseAndEvaluateOclExpressionWithMixOfPrimitiveAndObjectTypesInCollectionLiteral() throws ParserException {
      OCLExpression expression4 = oclHelper.createQuery("Set{1, 2, self}->select(i | i.oclIsKindOf(Integer))");
      Object result4 = ocl.evaluate(CompanyFactory.eINSTANCE.createDepartment(), expression4);
      assertTrue(result4 instanceof Collection);
      assertTrue(((Collection<?>) result4).contains(1));
      assertTrue(((Collection<?>) result4).contains(2));
  }

  /**
   * Check if invalid can be passed into an operation as argument
   */
  @Test
  public void testParseAndEvaluateOclExpressionWithInvalidInOperationArgument() throws ParserException {
      EClass cl = CompanyPackage.eINSTANCE.getDepartment();
      EOperation op = EcoreFactory.eINSTANCE.createEOperation();
		try {
			op.setName("myOp");
			op.setEType(EcorePackage.eINSTANCE.getEBoolean());
			EParameter param = EcoreFactory.eINSTANCE.createEParameter();
			param.setName("humba");
			param.setEType(org.eclipse.emf.ecore.EcorePackage.eINSTANCE
					.getEClassifier());
			op.getEParameters().add(param);
			cl.getEOperations().add(op);
			oclHelper.setOperationContext(cl, op);
			oclHelper.createBodyCondition("humba.oclIsInvalid()");
			oclHelper.setContext(cl);
			OCLExpression expression4 = oclHelper
					.createQuery("self.myOp(invalid)");
			Object result4 = ocl.evaluate(
					CompanyFactory.eINSTANCE.createDepartment(), expression4);
			assertEquals(true, result4);
		} finally {
    	  cl.getEOperations().remove(op);
      }
  }

    /**
     * Ensure that "or" and "and" do shortcut evaluation for invalid arguments
     */
    @Test
    public void testParseAndEvaluateOclExpressionWithInvalidInBooleanShortcutEval() throws ParserException {
        OCLExpression expression4 = oclHelper.createQuery("false and invalid");
        Object result4 = ocl.evaluate(null, expression4);
        assertEquals(false, result4);
        OCLExpression expression5 = oclHelper.createQuery("true or invalid");
        Object result5 = ocl.evaluate(null, expression5);
        assertEquals(true, result5);
        OCLExpression expression6 = oclHelper.createQuery("(invalid or true).oclIsInvalid()");
        Object result6 = ocl.evaluate(null, expression6);
        assertEquals(false, result6);
        OCLExpression expression7 = oclHelper.createQuery("(invalid and false).oclIsInvalid()");
        Object result7 = ocl.evaluate(null, expression7);
        assertEquals(false, result7);
        OCLExpression expression8 = oclHelper.createQuery("(invalid or true)");
        Object result8 = ocl.evaluate(null, expression8);
        assertEquals(true, result8);
        OCLExpression expression9 = oclHelper.createQuery("(invalid and false)");
        Object result9 = ocl.evaluate(null, expression9);
        assertEquals(false, result9);
    }

  /**
   * Testing if a let-expression evaluates to OclInvalid if the initExpression evaluates to OclInvalid although
   * the variable is not used in the "in" expression.
   */
  @Test
  public void testParseAndEvaluateOclExpressionWithInvalidLetInitExpression() throws ParserException {
      OCLExpression expression4 = oclHelper
              .createQuery("let x:Integer=self.name.size() in 1+2");
      Object result4 = ocl.evaluate(null, expression4);
      assertEquals(3, result4);
  }

    /**
     * Testing if two iterator variables appear as such
     */
    @Test
    public void testParseAndEvaluateOclExpressionForAllWithTwoIterators() throws ParserException {
        OCLExpression expression4 = oclHelper
                .createQuery("Set{1, 2, 3}->forAll(i, j | i+j <> 7)");
        assertEquals(2, ((LoopExp) expression4).getIterator().size());
        Object result4 = ocl.evaluate(param, expression4);
        assertEquals(true, result4);
    }

    /**
     * Testing if an iterate's accumulator expression is really evaluated even when the iterate is applied to an empty collection
     */
    @Test
    public void testParseAndEvaluateOclExpressionAccumulatorForIterateOnEmptyCollection() throws ParserException {
        OCLExpression expression4 = oclHelper
                .createQuery("let s:Set(Integer)=Set{} in s->iterate(i:Integer; acc:Integer=1 | acc+1)");
        Object result4 = ocl.evaluate(param, expression4);
        assertEquals(1, result4);
    }

  /**
   * Testing if shadowing a variable by an iterator leads to incorrect results because the shadowed
   * variable is overwritten by the iterator values
   */
  @Test
  public void testParseAndEvaluateOclExpressionIteratorShadowingLetVariable() throws ParserException
  {
    param.setOwnedTypeDefinition(ctd);
    ctd.setClazz(null);
    try {
        OCLExpression expression4 = oclHelper.createQuery("let i:Integer=1 in if self.ownedTypeDefinition->select(i|i.oclAsType(ClassTypeDefinition).clazz->notEmpty())->isEmpty() then i else 0 endif");
        Object result4 = ocl.evaluate(param, expression4);
        assertEquals(1, result4);
    } catch (SemanticException e) {
        // it's ok if the OCL implementation doesn't accept shadowing:
        assertEquals("Variable name already used: (i)", e.getMessage());
    }
  }

  /**
   * Ensures that an OclInvalid value does not pass a select filter, yet the select iterator
   * returns a valid result
   */
  @Test
  public void testParseAndEvaluateOclExpressionWithTupleWithNull() throws ParserException
  {
    param.setName(null);
    OCLExpression expression5 = oclHelper.createQuery("Tuple{c:Tuple(d:String)=Tuple{d=self.name}}.c.d");
    Object result5 = ocl.evaluate(param, expression5);
    assertNull(result5);
  }

  /**
   * Ensures that an OclInvalid value does not pass a select filter, yet the select iterator
   * returns a valid result
   */
  @Test
  public void testParseAndEvaluateOclExpressionWithCollectOfNullValue() throws ParserException
  {
    OCLExpression expression5 = oclHelper.createQuery("Set{1, 2}->collect(null)");
    Object result5 = ocl.evaluate(param, expression5);
    assertEquals(2, ((Collection<?>) result5).size());
    assertTrue(((Collection<?>) result5).contains(null));
  }

  /**
   * Ensures that an OclInvalid value does not pass a select filter, yet the select iterator
   * returns a valid result
   */
  @Test
  public void testParseAndEvaluateOclExpressionWithIncludingNullInSequence() throws ParserException
  {
    OCLExpression expression5 = oclHelper.createQuery("Sequence{1}->including(null)");
    Object result5 = ocl.evaluate(param, expression5);
    assertEquals(2, ((Collection<?>) result5).size());
    assertTrue(((Collection<?>) result5).contains(null));
  }

  /**
   * Ensures that an OclInvalid value does not pass a select filter, yet the select iterator
   * returns a valid result
   */
  @Test
  public void testParseAndEvaluateOclExpressionWithSizeOverSequenceContainingNull() throws ParserException
  {
    OCLExpression expression5 = oclHelper.createQuery("Sequence{1}->including(null)->size()");
    Object result5 = ocl.evaluate(param, expression5);
    assertEquals(2, result5);
  }

  /**
   * Ensures that an OclInvalid value does not pass a select filter, yet the select iterator
   * returns a valid result
   */
  @Test
  public void testParseAndEvaluateOclExpressionWithCollectOverOclInvalid() throws ParserException
  {
    OCLExpression expression5 = oclHelper.createQuery("Set{self, invalid}->collect(i | i)");
    Object result5 = ocl.evaluate(param, expression5);
    assertInvalid(result5);
  }

  /**
   * Ensures that an OclInvalid value propagates from a collection literal to the overall expression
   */
  @Test
  public void testParseAndEvaluateOclExpressionWithSelectOverOclInvalid() throws ParserException
  {
    OCLExpression expression5 = oclHelper.createQuery("Set{self, invalid}->select(i | i.name = 'p')");
    Object result5 = ocl.evaluate(param, expression5);
    assertInvalid(result5);
  }

  @Test
  public void testParseAndEvaluateOclExpression() throws ParserException
  {
    OCLExpression expression = oclHelper.createQuery("self.ownedTypeDefinition.oclAsType(data::classes::ClassTypeDefinition).clazz");
    Object result = ocl.evaluate(param, expression);
    assertEquals(class1, result);
  }

  @Test
  public void testParseAndEvaluateOclExpressionWithOperationCallOnNullValue() throws ParserException
  {
    param.setOwnedTypeDefinition(null);
    OCLExpression expression2 = oclHelper.createQuery("self.ownedTypeDefinition.getInnermost()");
    Object result = ocl.evaluate(param, expression2);
    assertEquals(ocl.getEnvironment().getOCLStandardLibrary().getInvalid(), result);
  }

  @Test
  public void testParseAndEvaluateOclExpressionWithPropertyCallOnNullValue() throws ParserException
  {
    param.setOwnedTypeDefinition(null);
    OCLExpression expression2 = oclHelper.createQuery("self.ownedTypeDefinition.oclAsType(data::classes::ClassTypeDefinition).clazz.oclIsInvalid()");
    Object result2 = ocl.evaluate(param, expression2);
    assertTrue((Boolean)result2);
  }

  @Test
  public void testParseAndEvaluateOclExpressionWithCollectOverNullValue() throws ParserException
  {
    param.setOwnedTypeDefinition(null);
    OCLExpression expression3 = oclHelper.createQuery("self.ownedTypeDefinition.oclAsType(data::classes::ClassTypeDefinition)->collect(clazz)");
    Object result3 = ocl.evaluate(param, expression3);
    assertEquals(0, ((Collection< ? >)result3).size());
  }

  @Test
  public void testParseAndEvaluateOclExpressionCollectWithBodyEvaluatingToNull() throws ParserException
  {
    param.setOwnedTypeDefinition(ctd);
    ctd.setClazz(null);
    OCLExpression expression4 = oclHelper.createQuery("self.ownedTypeDefinition.oclAsType(data::classes::ClassTypeDefinition)->collect(clazz)");
    Object result4 = ocl.evaluate(param, expression4);
    assertTrue(((Bag< ? >)result4).contains(null));
  }

  @Test
  public void testParseAndEvaluateOclExpressionWithImplicitCollectOverOperationCallResult() throws ParserException
  {
    OCLExpression expression4 = oclHelper.createQuery("self.ownedTypeDefinition.oclAsType(data::classes::ClassTypeDefinition).clazz.getAssociationEnds().otherEnd()");
    Object result4 = ocl.evaluate(param, expression4);
    assertTrue(((Collection<?>) result4).isEmpty());
  }

  @Test
  public void testParseAndEvaluateOclExpressionWithDelegatesToSimulation() throws ParserException
  {
    OCLExpression expression4 = oclHelper.createQuery("self.ownedTypeDefinition.oclAsType(data::classes::ClassTypeDefinition).clazz.getAssociationEnds().otherEnd()->select(delegation->notEmpty()).type.clazz->reject(c|c=self)->asSet()");
    Object result4 = ocl.evaluate(param, expression4);
    assertTrue(((Collection<?>) result4).isEmpty());
  }

  @Test
  public void testParseAndEvaluateOclExpressionWithImplicitSetLiteral() throws ParserException
  {
    OCLExpression expression4 = oclHelper.createQuery("self.ownedTypeDefinition->isEmpty()");
    Object result4 = ocl.evaluate(param, expression4);
    assertFalse((Boolean) result4);
  }

  @Test
  public void testParseAndEvaluateOclExpressionWithImplicitSetLiteralCheckingForIsEmpty() throws ParserException
  {
    param.setOwnedTypeDefinition(null);
    OCLExpression expression5 = oclHelper.createQuery("self.ownedTypeDefinition->isEmpty()");
    Object result5 = ocl.evaluate(param, expression5);
    assertTrue((Boolean) result5);
  }

  @Test
  public void testParseAndEvaluateOclExpressionWithNullInSetLiteral() throws ParserException
  {
	    param.setOwnedTypeDefinition(null);
	    OCLExpression expression5 = oclHelper.createQuery("Set{null}->isEmpty()");
	    Object result5 = ocl.evaluate(param, expression5);
	    assertFalse((Boolean) result5);
	    OCLExpression expression6 = oclHelper.createQuery("null->isEmpty()");
	    Object result6 = ocl.evaluate(param, expression6);
	    assertTrue((Boolean) result6);
  }

  @Test
  public void testParseAndEvaluateOclExpressionWithEmptySetLiteralIncludingNull() throws ParserException
  {
    OCLExpression expression4 = oclHelper.createQuery("Set{}->including(null)->isEmpty()");
    Object result4 = ocl.evaluate(param, expression4);
    assertFalse((Boolean) result4);
  }

}
