package android.malware.detection.logic;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.gmt.modisco.java.actions.DefaultDiscoverer;
import org.eclipse.gmt.modisco.java.actions.DiscoverJavaModelFromJavaProject;
import org.eclipse.gmt.modisco.xml.discoverer.actions.XMLModelDiscoverer;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.m2m.atl.core.ATLCoreException;
import org.eclipse.ui.IWorkbenchWindow;

import android.malware.detection.transformations.AndroidSecurityExtractor;
import android.malware.detection.transformations.DetectionByICCPattern;
import android.malware.detection.transformations.DetectionMaliciousAction;
import android.malware.detection.transformations.CreateFeatureModel;
import android.malware.detection.transformations.DetectionMaliciousPermission;
import malware.android.analysis.Utility;



public class Extractortwo {
	
	private IProject javaProject;
	private IFile AndroidManestifDescriptor1;
	
	private String javaProjectPath;
	private String javaProjectPath1;
	private String AndroidManifestDescriptorPath;
	private String AndroidManifestDescriptorPath1;
	private String outputMaliciousPermissionPath1;
	
	private String outputMaliciousActionPath1;
	private String outputFeatureModel;
	private String outputICCPatternPath1;
	private String AndroidSecurityPath1;
	private String AndroidSecurityPath11;
	private String ManifestFile;
	private String XMLMODEL1;
	private String JavaMODEL1;
	private List<String> properties;
	
	public Extractortwo(IProject javaProject, String Manifest) {
		
		this.javaProject = javaProject;
		this.javaProjectPath = this.javaProject.getLocation().toFile().getPath();
		this.javaProjectPath1=this.javaProject.getLocation().toString();
		System.out.print(" javaProjectPath----------------->>>>>>>>>>>   "+ this.javaProjectPath);
		System.out.print(" javaProjectPath1----------------->>>>>>>>>>>   "+ this.javaProjectPath1);
	
		this.outputMaliciousPermissionPath1= "file:/"+ ResourcesPlugin.getWorkspace().getRoot().getLocation().toString()+ "/" + this.javaProject.getName() + "/" + "MaliciousPermissions.xmi";
		
		//for feature model
		this.outputFeatureModel= "file:/"+ ResourcesPlugin.getWorkspace().getRoot().getLocation().toString()+ "/" + this.javaProject.getName() + "/" + "FeatureModel.xmi";

		this.outputICCPatternPath1= "file:/"+ ResourcesPlugin.getWorkspace().getRoot().getLocation().toString()+ "/" + this.javaProject.getName() + "/" + "ICCPattern.xmi";
		this.AndroidSecurityPath1= "file:/"+ ResourcesPlugin.getWorkspace().getRoot().getLocation().toString()+ "/" + this.javaProject.getName() + "/" + "AndroidSecurity.xmi";
		this.AndroidSecurityPath11= "file:/"+ this.javaProjectPath1+"/"+"AndroidSecurity.xmi";
		System.out.print(" AndroidSecurityPath11----------------->>>>>>>>>>>   "+ this.AndroidSecurityPath11);
		System.out.print(" AndroidSecurityPath1----------------->>>>>>>>>>>   "+ this.AndroidSecurityPath1);
		
		this.ManifestFile= "file:/"+ ResourcesPlugin.getWorkspace().getRoot().getLocation().toString()+ "/" + this.javaProject.getName() + "/" + "AndroidManifest.xml";
		this.XMLMODEL1="file:/"+ this.javaProjectPath1+ "/"+"AndroidManifest_xml.xmi";
		
		System.out.print(" XMLMODEL1----------------->>>>>>>>>>>   "+ this.XMLMODEL1);
		
	//	this.mergedPIMPath = this.javaProjectPath + "\\" + this.javaProject.getName() + ".pim.xmi";
		
		if (Manifest != null) {		
			this.AndroidManifestDescriptorPath = this.getFullPath(Manifest);
			this.AndroidManifestDescriptorPath1 = "file:/"+ ResourcesPlugin.getWorkspace().getRoot().getLocation().toString()+ "/" + this.javaProject.getName() + "/" + "AndroidManifest.xml";
			//this.AndroidXMIDescriptorPath = this.AndroidManifestDescriptorPath + ".xmi";
			//this.AndroidManestifDescriptor = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(this.AndroidManifestDescriptorPath));	
			this.AndroidManestifDescriptor1 = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(this.AndroidManifestDescriptorPath1));
		}
		
		System.out.print("   ManifestFile :" +  this.ManifestFile);
		
		//this.properties = properties;
	}
	
	public String getFullPath(String path) {
		String output = "";
		if (path.startsWith("platform:/resource/")) {
			String workspacePath = ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile().getPath();
			String filePath = path.replaceAll("platform:/resource/", "");
			output = workspacePath + "\\" + filePath.replaceAll("/", "\\\\");
		}
		else if (path.startsWith("file:/")) {
			output = path.replaceAll("file:/", "");
		}
		
		return output;
	}
	
	public void execute() throws IOException, ATLCoreException, CoreException {

		this.generateModels();
		this.extractSecurityFromAndroid();
		this.CreateFeatureModel();;
		this.detectionICCPattertn();
		detectionMaliciousPermissiontechnique();
		
		

		System.out.print("   >>>>>>>>>>>>>>>>>>>>>>>>propertie" + this.properties);
		
		this.cleanProject();	
	}
	
	private void cleanProject() throws CoreException {
		
		this.refreshProjet();
		this.refreshProjet();
	}
	
	private void deleteFile(String path) throws CoreException {
		IFile toDelete = null;
		try {
			toDelete = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(path));
			if (toDelete != null) {
				toDelete.delete(true, null);
			}
		}
		catch (Exception e) {}
	}
	
	private void refreshProjet() throws CoreException {
		this.javaProject.refreshLocal(IResource.DEPTH_INFINITE, null);
	}
	
	private void generateModels() throws IOException {
		this.generateModelCode(this.javaProject);
	System.out.print("   AndroidManestifDescriptor1  :" + this.AndroidManifestDescriptorPath1);
			this.generateModelXML(this.AndroidManestifDescriptor1);
	
	}
	
	
	public void detectionMaliciousPermissiontechnique()throws IOException, ATLCoreException  {
		System.out.print("Malicious Permissions");
		DetectionMaliciousPermission transformation=new DetectionMaliciousPermission();
	System.out.print("        " + Utility.ANomaly_MODELS);
		try {
			transformation.runATL(this.AndroidSecurityPath11,this.outputMaliciousPermissionPath1);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.print("Malicious Permissions end");
	}
	
	//FOR ACTIONS
	public void detectionMaliciousActions()throws IOException, ATLCoreException  {
		System.out.print("Malicious Actions");
		DetectionMaliciousAction transformation=new DetectionMaliciousAction();
	System.out.print("        " + Utility.ANomaly_MODELS);
		try {
			transformation.runATL(this.AndroidSecurityPath11,this.outputMaliciousActionPath1);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.print("Malicious Actions end");	

	}
	
	
	//For category
	public void CreateFeatureModel()throws IOException, ATLCoreException  {
		System.out.print("Feature Model");
		CreateFeatureModel transformation=new CreateFeatureModel();
	System.out.print("        " + Utility.ANomaly_MODELS);
		try {
			transformation.runATL(this.AndroidSecurityPath11,this.outputFeatureModel);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.print("Feature Model end");
	}
	
	public void detectionICCPattertn() throws IOException, ATLCoreException {
		System.out.print("ICC Pattern");
		DetectionByICCPattern transformation=new DetectionByICCPattern();
	System.out.print("        " + Utility.ANomaly_MODELS);
		try {
			transformation.runATL(this.AndroidSecurityPath11,this.outputFeatureModel, this.outputICCPatternPath1);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.print("ICC end");		

	}
	
	public void extractSecurityFromAndroid() throws IOException, ATLCoreException {
		
		System.out.print("Extract android model ");
		AndroidSecurityExtractor transformation=new AndroidSecurityExtractor();
		System.out.print(ResourcesPlugin.getWorkspace().getRoot().getLocation().toString()+ "/" + this.javaProject.getName() + "/" + "app.android.xmi");
		
		try {
		transformation.runATL(this.XMLMODEL1, this.JavaMODEL1, this.AndroidSecurityPath11);
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
			
		System.out.print("********" + this.AndroidSecurityPath1);
		System.out.print("Extract android model      end");
		
		
	}
	
	
	
	@SuppressWarnings("unchecked")
	public void generateModelCode(IProject project) throws IOException {
		IJavaProject javaProject = JavaCore.create(project);
		 System.out.print("   Create a discoverer for a Java project");
		//Create a discoverer for a Java project
		DiscoverJavaModelFromJavaProject javaDiscoverer = new DiscoverJavaModelFromJavaProject();

		//Parameters of the discoverer
		@SuppressWarnings("rawtypes")
		Map javaDiscoveryParameters = new HashMap();
		javaDiscoveryParameters.put(DefaultDiscoverer.PARAMETER_SILENT_MODE, true);
		javaDiscoveryParameters.put(DefaultDiscoverer.PARAMETER_BROWSE_RESULT, false);

		//Execute the discoverer (javaProject is a IJavaProject) and serialize the model to <project_name>.javaxmi
		javaDiscoverer.discoverElement(javaProject, javaDiscoveryParameters);
		
	//	this.JavaMODEL="file:/"+ ResourcesPlugin.getWorkspace().getRoot().getLocation().toString()+ "/" + this.javaProject.getName() + "/" + this.javaProject.getName() + ".javaxmi";
		//this.JavaMODEL1=JavaMODEL.replace("file:/D:/dev/project/runtime-New_configuration(13)", "");
		this.JavaMODEL1="file:/"+ this.javaProjectPath1+ "/"+ this.javaProject.getName()+ ".javaxmi";
		System.out.print("   JavaMODEL1:  "+this.JavaMODEL1);
		return;
	}
	
	
	@SuppressWarnings("unchecked")
	public void generateModelXML(IFile source) {
        System.out.print("  llllllllllllllllllllllllllllllllllllllllllll XML discovery:");
        
        XMLModelDiscoverer discoverer = new XMLModelDiscoverer();
     // launch the discovery
        Map xmlDiscoveryParameters = new HashMap();
		xmlDiscoveryParameters.put(XMLModelDiscoverer.PARAMETER_SILENT_MODE, true);
		xmlDiscoveryParameters.put(XMLModelDiscoverer.PARAMETER_SERIALIZE_XMI, true);
    Resource xmlResource = discoverer.getResourceResult();
     System.out.print("    xmlResource: " + xmlResource);     
		System.out.print("   XML model:" + xmlDiscoveryParameters);
		 System.out.print(" end  XML discovery:");	
	}
	
}

