/*
 * Copyright (c) 2002-2003 IST-2004-2006-511731 ModelWare - ModelBus.
 * All rights reserved.
 *
 * This software is published under the terms of the ModelBus Software License
 * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * A copy of ModelBus Software License is provided with this distribution in
 * doc/LICENSE.txt file.
 */

/*
 * Created on 5 juil. 2005
 *
 */
package org.eclipse.mddi.modelbus.adapter.test.unit;

import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Vector;

import org.apache.log4j.Logger;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.impl.EcorePackageImpl;
import org.eclipse.mddi.modelbus.adapter.infrastructure.LoggerConfigurator;
import org.eclipse.mddi.modelbus.adapter.infrastructure.serialize.emf_xmi.Emf2XmiConversion;
import org.eclipse.uml2.Class;
import org.eclipse.uml2.Package;
import org.eclipse.uml2.UML2Factory;
import org.eclipse.uml2.impl.UML2PackageImpl;
import org.eclipse.mddi.modelbus.description.DescriptionFactory;
import org.eclipse.mddi.modelbus.description.ModelBusPackaging;
import org.eclipse.mddi.modelbus.description.abstract_.*;

import org.eclipse.mddi.modelbus.description.abstract_.impl.AbstractPackageImpl;
import org.eclipse.mddi.modelbus.description.concrete.*;
import org.eclipse.mddi.modelbus.description.concrete.impl.ConcretePackageImpl;
import org.eclipse.mddi.modelbus.description.impl.DescriptionPackageImpl;

/**
 * Provides shared methods for testing
 * 
 * @author Prawee Sriplakich, Andrey Sadovykh (LIP6)
 *
 *
 */
public class Util {
    
    private static Logger logger = Logger.getLogger(Util.class);
    
  public static Collection createEcoreModel() {
      Collection model = new Vector();
      EcoreFactory factory = EcorePackageImpl.init().getEcoreFactory();
      for(int i=0; i<5; i++) {
        EPackage p = factory.createEPackage();
        p.setName("P" +i);
        //model.add(p);
        EClass c = factory.createEClass();
        c.setName("Class" +i);
        p.getEClassifiers().add(c);
        model.add(p);        
      }   
      
      logger.info("Created model size:"+model.size());
      return model;
  }
  
  public static Collection createUml2Model() {
      Collection model = new Vector();
      UML2Factory factory = UML2PackageImpl.init().getUML2Factory();
      for(int i=0; i<5; i++) {
          Package p = factory.createPackage();
          p.setName("P" +i);
          model.add(p);
          Class c = factory.createClass();
          c.setName("Class" +i);
          p.getOwnedMembers().add(c);
          
          
          model.add(c);
          
      }
      try {
        logger.info("Created model:"+Emf2XmiConversion.convertToString(model));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
      return model;      
  }
  
  public static AbstractFactory abstractFactory = AbstractPackageImpl.init().getAbstractFactory();
  public static ConcreteFactory concreteFactory = ConcretePackageImpl.init().getConcreteFactory(); 
  public static DescriptionFactory descFactory = DescriptionPackageImpl.init().getDescriptionFactory();
  
  public static Tool createToolDescription() {
      Tool tool = concreteFactory.createTool();
      tool.setName("Tool1");
      ModelingServiceInterface msi = abstractFactory.createModelingServiceInterface();
      msi.setName("ModelingServiceInterface1");
      ModelingService ms = abstractFactory.createModelingService();
      ms.setName("service1");
      msi.getService().add(ms);
      tool.setInterface(msi);
      ModelBusPackaging p = descFactory.createModelBusPackaging();
      p.getContent().add(tool);
      p.getContent().add(msi);
      
      return tool;      
  }
  
  
  /**
 * Compares two models.
 * First the sizes of 2 models are compared. 
 * Then for all objects in model1, 
 * we find the same object with the same name and the same type in the model2.
 * 
 * <p>name of the object is the value of the property "name". 
 * If the object does not have this property, the name is not compared.
 * 
 * <p>type of the object is the metaclass of which the object is instance
 * 
 * @param model1
 * @param model2
 * @return true if equal
 * 
 *
 */
public static boolean compareModels(Collection model1, Collection model2) {
   if(model1.size()!=model2.size()) {
       logger.info("size not equal:"+model1.size()+"!="+model2.size());
       return false;
   }
    
   Iterator it = model1.iterator();
   while(it.hasNext()) {       
     EObject o = (EObject) it.next();
     EStructuralFeature f = o.eClass().getEStructuralFeature("name");
     if(f==null) break;
     String name = (String) o.eGet(f);
     boolean found = false;     
     Iterator it2 = model2.iterator();
     while(it2.hasNext()) {
       EObject o2 = (EObject) it2.next();
       if(o.eClass().equals(o2.eClass())) {
         String name2 = (String) o2.eGet(f);
         found = name.equals(name2);
         if(found) break;
       }
     }
     if(!found) {
       LoggerConfigurator.configure();
       logger.info("element not found "+name);
       return false;
     }
   }
   return true;
}
  
/**
 * getSequenceDiagramModelAdd description 
 * 
 * @return
 */

  public  static Collection getUmlSequenceDiagramModel() {
    
    
    return null;
  }

}
