package org.ut.cmldep;

import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.ec2.model.InstanceType;
import org.cloudml.core.*;
import org.cloudml.core.credentials.Credentials;
import org.ut.cmldep.amazon.request.AWSClients;

import static org.ut.cmldep.CMLDeployer.*;

public class InitialDeploymentConfiguration {
	
	
	private Deployment deployment;
	
	public Deployment getDeployment() {
		return deployment;
	}

	public void setDeployment(Deployment deployment) {
		this.deployment = deployment;
	}
	
	public void setCredentionals(Credentials credentials){
		this.deployment.getProviders().toList().get(0).setCredentials(credentials);
	}
	
	/**
     * Read credentials from 
     * 
     * @return Credentials object.
     */
    private Credentials getCredentials(){
    	
    	Credentials credentials = new Credentials() {
        	
        	PropertiesCredentials credentials = AWSClients.getProperties();
			
			@Override
			public String getPassword() {

				return credentials.getAWSSecretKey();
			}
			
			@Override
			public String getLogin() {
				return credentials.getAWSAccessKeyId();
			}
		};
		
		return credentials;
    	
    }


	public InitialDeploymentConfiguration(){

		
		deployment = new Deployment();
		deployment.setDelay(5);
		//deployment.setKillingTime(2);
		deployment.setSupportedTypes(new String[]{"m1.small", "m3.medium", "m3.large"});
		
		Provider provider = new Provider();
		provider.setName("aws-ec2");
		provider.setCredentials(getCredentials());


		ProvidedPort defaultProvidedPort = new ProvidedPort("defaultProvidedPort");
		defaultProvidedPort.setPortNumber(80);
		defaultProvidedPort.setLocal(false);

		RequiredPort defaultRequiredPort = new RequiredPort("defaultRequiredPort");
		defaultRequiredPort.setPortNumber(80);
		defaultRequiredPort.setOptional(false);
		defaultRequiredPort.setLocal(false);

		Resource lbSoft = new Resource("lbSoft");
		lbSoft.setRetrieveCommand("sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/lb.sh; sudo sh lb.sh");

		ProvidedPort dbProvidedPort = new ProvidedPort("dbProvidedPort");
		dbProvidedPort.setLocal(false);
		dbProvidedPort.setPortNumber(3306);

		Resource dbSoft = new Resource("dbSoft");
		dbSoft.setRetrieveCommand("sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/db.sh; sudo bash db.sh");

		RequiredPort dbRequiredPort = new RequiredPort("dbRequiredPort");
		dbRequiredPort.setPortNumber(3306);
		dbRequiredPort.setOptional(false);
		dbRequiredPort.setLocal(false);

		Resource wikiSoft = new Resource("wikiSoft");
		wikiSoft.setRetrieveCommand("sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/wiki_alt.sh; sudo sh wiki_alt.sh");

		Property pr = new Property("os_Name");
		pr.setName("os");
		pr.setValue("Ubuntu");


		ProvidedExecutionPlatform vmOS = new ProvidedExecutionPlatform("vmOS");
		vmOS.getProperties().add(pr);

		RequiredExecutionPlatform platform = new RequiredExecutionPlatform("platform");


		InternalComponent lb = new InternalComponent("lb", platform);
		lb.getResources().add(lbSoft);
		lb.setRequiredExecutionPlatform(platform);
		lb.getRequiredPorts().add(defaultRequiredPort);
		lb.getProvidedPorts().add(dbProvidedPort);



		InternalComponent db = new InternalComponent("db", platform);
		db.getResources().add(dbSoft);
		db.getProvidedPorts().add(dbProvidedPort);
		db.getProvidedPorts().add(defaultProvidedPort);
		db.getRequiredPorts().add(defaultRequiredPort);
		db.setRequiredExecutionPlatform(platform);

		InternalComponent wiki = new InternalComponent("wiki", platform);
		wiki.getResources().add(wikiSoft);
		wiki.getRequiredPorts().add(dbRequiredPort);
		wiki.getProvidedPorts().add(defaultProvidedPort);
		wiki.setRequiredExecutionPlatform(platform);

		VM t1_micro = new VM("T1Micro", provider);
		t1_micro.setProviderSpecificTypeName(InstanceType.M1Small.toString());
		t1_micro.setLocation(LOCATION);
		t1_micro.setSshKey(SHH_KEY);
		t1_micro.setSecurityGroup(SECURITY_GROUP);
		t1_micro.setGroupName(GROUP_NAME);
		t1_micro.setPrivateKey(PRIVATE_KEY);
		t1_micro.setImageId(IMAGE_ID);
		t1_micro.setIs64os(true);
		t1_micro.getProvidedExecutionPlatforms().add(vmOS);

		VM t1_medium = new VM("M1.medium", provider);
		t1_medium.setProviderSpecificTypeName(InstanceType.M3Medium.toString());
		t1_medium.setLocation(LOCATION);
		t1_medium.setSshKey(SHH_KEY);
		t1_medium.setSecurityGroup(SECURITY_GROUP);
		t1_medium.setGroupName(GROUP_NAME);
		t1_medium.setPrivateKey(PRIVATE_KEY);
		t1_medium.setImageId(IMAGE_ID);
		t1_medium.setIs64os(true);
		t1_medium.getProvidedExecutionPlatforms().add(vmOS);

		VMInstance dbVM = new VMInstance("iurii-db--1" + "-" + String.valueOf(System.currentTimeMillis()), t1_medium);
		VMInstance wikiVM = new VMInstance("iurii-wiki--1" + "-" + String.valueOf(System.currentTimeMillis()), t1_micro);

		InternalComponentInstance dbInstance = new InternalComponentInstance("db--1", db);
		InternalComponentInstance wikiInstance = new InternalComponentInstance("wiki--1", wiki);


		Resource installWiki = new Resource("installWiki");
		installWiki.setRetrieveCommand("sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/install_wiki_alt.sh; sudo sh install_wiki_alt.sh");

		Relationship installWikiRel = new Relationship("InstallWikiRel", dbRequiredPort, dbProvidedPort);
		installWikiRel.setClientResource(installWiki);

		RelationshipInstance installWikiRelInstance = new RelationshipInstance("installWikiRel",
				wikiInstance.getRequiredPorts().ofType(dbRequiredPort),
				dbInstance.getProvidedPorts().ofType(dbProvidedPort),
				installWikiRel);


		Resource addToLB = new Resource("addToLB");
		addToLB.setRetrieveCommand("sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/add_to_lb_n.sh; sudo sh add_to_lb_n.sh");

		Relationship addToLBRel = new Relationship("addToLBRel", defaultRequiredPort, defaultProvidedPort);
		addToLBRel.setClientResource(addToLB);

		ExecuteInstance dbExecInstance = new ExecuteInstance("dbExecInstance", dbInstance, dbVM.getProvidedExecutionPlatforms().firstMatchFor(db));
		ExecuteInstance wikiExecInstance = new ExecuteInstance("wikiExecInstance", wikiInstance, wikiVM.getProvidedExecutionPlatforms().firstMatchFor(wiki));
		//ExecuteInstance lbExecInstance = new ExecuteInstance("lbExecINstance", lbInstance, lbVM.getProvidedExecutionPlatforms().firstMatchFor(lb));
		//ExecuteInstance test = new ExecuteInstance

		String addCommand = "sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/add_to_lb_n.sh; sudo sh add_to_lb_n.sh";
		String removeCommand = "sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/remove_from_lb.sh; sudo sh remove_from_lb.sh";
		ScalableComponent testS1 = new ScalableComponent("region-1", wikiExecInstance, addCommand, removeCommand);
		testS1.addInternalRelationships(installWikiRelInstance);
		testS1.setSupportedTypesOfInstances(new String[]{"m1.small", "m3.medium", "m3.large"});

		deployment.getProviders().add(provider);


		deployment.getExecuteInstances().add(dbExecInstance);
		deployment.getExecuteInstances().add(wikiExecInstance);

		deployment.getComponentInstances().add(dbInstance);
		deployment.getComponentInstances().add(wikiInstance);

		deployment.getComponents().add(db);
		deployment.getComponents().add(wiki);
//		deployment.getComponents().add(lb);
		deployment.getComponents().add(t1_medium);
		deployment.getComponents().add(t1_micro);

		deployment.getComponentInstances().add(dbVM);
		deployment.getComponentInstances().add(wikiVM);

		deployment.getRelationships().add(installWikiRel);

		deployment.getRelationshipInstances().add(installWikiRelInstance);
		deployment.getScalableComponents().add(testS1);

	}


	/*public InitialDeploymentConfiguration(){

		deployment = new Deployment();
		deployment.setDelay(5);
		deployment.setSupportedTypes(new String[]{"m1.small", "m3.medium", "m3.large"});

		Provider provider = new Provider();
		provider.setName("aws-ec2");
		provider.setCredentials(getCredentials());


		ProvidedPort defaultProvidedPort = new ProvidedPort("defaultProvidedPort");
		defaultProvidedPort.setPortNumber(80);
		defaultProvidedPort.setLocal(false);

		RequiredPort defaultRequiredPort = new RequiredPort("defaultRequiredPort");
		defaultRequiredPort.setPortNumber(80);
		defaultRequiredPort.setOptional(false);
		defaultRequiredPort.setLocal(false);

		Resource mainApp = new Resource("mainApp");
		mainApp.setRetrieveCommand("sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/ex2/app1/install.sh; sudo sh install.sh");

		Resource addApp1 = new Resource("addApp_1");
		addApp1.setRetrieveCommand("sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/ex2/app2/install.sh; sudo sh install.sh");

		Resource addApp2 = new Resource("addApp_2");
		addApp2.setRetrieveCommand("sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/ex2/app3/install.sh; sudo sh install.sh");

		Resource unbound = new Resource("unbound");
		unbound.setRetrieveCommand("sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/unbound/install_unbound.sh; sudo sh install_unbound.sh");

		ProvidedPort firstAddAppProvidedPort = new ProvidedPort("addAppProvidedPort1");
		firstAddAppProvidedPort.setLocal(false);
		firstAddAppProvidedPort.setPortNumber(3000);

		ProvidedPort secondAddAppProvidedPort = new ProvidedPort("addAppProvidedPort2");
		secondAddAppProvidedPort.setLocal(false);
		secondAddAppProvidedPort.setPortNumber(3000);

		RequiredPort firstAddAppRequiredPort = new RequiredPort("firstAddAppRequiredPort");
		firstAddAppRequiredPort.setPortNumber(3000);
		firstAddAppRequiredPort.setOptional(false);
		firstAddAppRequiredPort.setLocal(false);

		RequiredPort secondAddAppRequiredPort = new RequiredPort("secondAddAppRequiredPort");
		secondAddAppRequiredPort.setPortNumber(3000);
		secondAddAppRequiredPort.setOptional(false);
		secondAddAppRequiredPort.setLocal(false);

		Resource wikiSoft = new Resource("wikiSoft");
		wikiSoft.setRetrieveCommand("sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/wiki.sh; sudo sh wiki.sh");

		Property pr = new Property("os_Name");
		pr.setName("os");
		pr.setValue("Ubuntu");


		ProvidedExecutionPlatform vmOS = new ProvidedExecutionPlatform("vmOS");
		vmOS.getProperties().add(pr);

		RequiredExecutionPlatform platform = new RequiredExecutionPlatform("platform");


		InternalComponent firstAddAppInternalComponent = new InternalComponent("firstAddAppInternalComponent", platform);
		firstAddAppInternalComponent.getResources().add(addApp1);
		firstAddAppInternalComponent.setRequiredExecutionPlatform(platform);
		firstAddAppInternalComponent.getProvidedPorts().add(firstAddAppProvidedPort);
		firstAddAppInternalComponent.getRequiredPorts().add(defaultRequiredPort);


		InternalComponent secondAddApp1InternalComponent = new InternalComponent("secondAddApp1InternalComponent", platform);
		secondAddApp1InternalComponent.getResources().add(addApp2);
		secondAddApp1InternalComponent.setRequiredExecutionPlatform(platform);
		secondAddApp1InternalComponent.getProvidedPorts().add(secondAddAppProvidedPort);
		secondAddApp1InternalComponent.getRequiredPorts().add(defaultRequiredPort);

		InternalComponent mainAppInternalComponent = new InternalComponent("mainAppIC", platform);
		mainAppInternalComponent.getResources().add(mainApp);
		mainAppInternalComponent.getResources().add(unbound);
		mainAppInternalComponent.getRequiredPorts().add(firstAddAppRequiredPort);
		mainAppInternalComponent.getRequiredPorts().add(secondAddAppRequiredPort);
		mainAppInternalComponent.setRequiredExecutionPlatform(platform);
		mainAppInternalComponent.getProvidedPorts().add(defaultProvidedPort);

		VM t1_micro = new VM("T1Micro", provider);
		t1_micro.setProviderSpecificTypeName(InstanceType.M1Small.toString());
		t1_micro.setLocation(LOCATION);
		t1_micro.setSshKey(SHH_KEY);
		t1_micro.setSecurityGroup(SECURITY_GROUP);
		t1_micro.setGroupName(GROUP_NAME);
		t1_micro.setPrivateKey(PRIVATE_KEY);
		t1_micro.setImageId(IMAGE_ID);
		t1_micro.setIs64os(true);
		t1_micro.getProvidedExecutionPlatforms().add(vmOS);

		VM t1_medium = new VM("M1.medium", provider);
		t1_medium.setProviderSpecificTypeName(InstanceType.M1Large.toString());
		t1_medium.setLocation(LOCATION);
		t1_medium.setSshKey(SHH_KEY);
		t1_medium.setSecurityGroup(SECURITY_GROUP);
		t1_medium.setGroupName(GROUP_NAME);
		t1_medium.setPrivateKey(PRIVATE_KEY);
		t1_medium.setImageId(IMAGE_ID);
		t1_medium.setIs64os(true);
		t1_medium.getProvidedExecutionPlatforms().add(vmOS);

		VMInstance firstAddAppVmInstance = new VMInstance("test-iurii-addapp1--1" + "-" + String.valueOf(System.currentTimeMillis()), t1_micro);
		VMInstance secondAddAppVmInstance = new VMInstance("test-iurii-addapp2--1" + "-" + String.valueOf(System.currentTimeMillis()), t1_micro);
		VMInstance mainAppVmInstance = new VMInstance("test-iurii-mainapp--1" + "-" + String.valueOf(System.currentTimeMillis()), t1_micro);


		InternalComponentInstance firstAppComInstance = new InternalComponentInstance("addApp1--1", firstAddAppInternalComponent);
		InternalComponentInstance secondAppComInstance = new InternalComponentInstance("addApp2--1", secondAddApp1InternalComponent);
		InternalComponentInstance mainAppComInstance = new InternalComponentInstance("mainApp1--1", mainAppInternalComponent);


		Resource linkFirstApp = new Resource("linkFirstApp");
		linkFirstApp.setRetrieveCommand("sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/ex2/link_first.sh; sudo sh link_first.sh");

		Resource linkSecondApp = new Resource("linkSecondApp");
		linkSecondApp.setRetrieveCommand("sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/ex2/link_second.sh; sudo sh link_second.sh");

		Relationship linkFirstAppRel = new Relationship("linkFirstAppRel", firstAddAppRequiredPort, firstAddAppProvidedPort);
		linkFirstAppRel.setClientResource(linkFirstApp);

		Relationship linkSecondAppRel = new Relationship("linkSecondAppRel", secondAddAppRequiredPort, secondAddAppProvidedPort);
		linkSecondAppRel.setClientResource(linkSecondApp);

		RelationshipInstance linkFirstAppRelInstance = new RelationshipInstance("linkFirstAppRelIns",
				mainAppComInstance.getRequiredPorts().ofType(firstAddAppRequiredPort),
				firstAppComInstance.getProvidedPorts().ofType(firstAddAppProvidedPort),
				linkFirstAppRel);

		RelationshipInstance linkSecondAppRelInstance = new RelationshipInstance("linkSecondAppRelIns",
				mainAppComInstance.getRequiredPorts().ofType(secondAddAppRequiredPort),
				secondAppComInstance.getProvidedPorts().ofType(secondAddAppProvidedPort),
				linkSecondAppRel);


		Resource addToLB = new Resource("addToLB");
		addToLB.setRetrieveCommand("sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/add_to_lb.sh; sudo sh add_to_lb.sh");

		Relationship addToLBRel = new Relationship("addToLBRel", defaultRequiredPort, defaultProvidedPort);
		addToLBRel.setClientResource(addToLB);

		ExecuteInstance firstAddAppExecInstance = new ExecuteInstance("firstAddAppExecInstance", firstAppComInstance, firstAddAppVmInstance.getProvidedExecutionPlatforms().firstMatchFor(firstAddAppInternalComponent));
		ExecuteInstance secondAddAppExecInstance = new ExecuteInstance("secondAddAppExecInstance", secondAppComInstance, secondAddAppVmInstance.getProvidedExecutionPlatforms().firstMatchFor(secondAddApp1InternalComponent));
		ExecuteInstance mainAddAppExecInstance = new ExecuteInstance("mainAddAppExecInstance", mainAppComInstance, mainAppVmInstance.getProvidedExecutionPlatforms().firstMatchFor(mainAppInternalComponent));

		String addCommand = "sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/add_to_lb_n.sh; sudo sh add_to_lb_n.sh";
		String removeCommand = "sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/remove_from_lb.sh; sudo sh remove_from_lb.sh";

		ScalableComponent reg1 = new ScalableComponent("region-1-test", firstAddAppExecInstance, addCommand, removeCommand);
		reg1.setSupportedTypesOfInstances(new String[]{"m1.small", "m3.medium", "m3.large"});
		reg1.setChangeDNSAddressCommand("sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/unbound/change_unbound_resolvimg.sh; sudo sh change_unbound_resolvimg.sh");

		ScalableComponent reg2 = new ScalableComponent("region-2-test", secondAddAppExecInstance, addCommand, removeCommand);
		reg2.setSupportedTypesOfInstances(new String[]{"m1.small", "m3.medium", "m3.large"});
		reg2.setChangeDNSAddressCommand("sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/unbound/change_unbound_resolvimg.sh; sudo sh change_unbound_resolvimg.sh");

		ScalableComponent reg3 = new ScalableComponent("region-3-test", mainAddAppExecInstance, addCommand, removeCommand);
		reg3.setSupportedTypesOfInstances(new String[]{"m1.small", "m3.medium", "m3.large"});
		reg3.setChangeDNSAddressCommand("sudo wget https://dl.dropboxusercontent.com/u/32823955/scripts/unbound/change_unbound_resolvimg.sh; sudo sh change_unbound_resolvimg.sh");

		deployment.getProviders().add(provider);

		deployment.getExecuteInstances().add(firstAddAppExecInstance);
		deployment.getExecuteInstances().add(secondAddAppExecInstance);
		deployment.getExecuteInstances().add(mainAddAppExecInstance);

		deployment.getComponentInstances().add(firstAppComInstance);
		deployment.getComponentInstances().add(secondAppComInstance);
		deployment.getComponentInstances().add(mainAppComInstance);


		deployment.getComponents().add(firstAddAppInternalComponent);
		deployment.getComponents().add(secondAddApp1InternalComponent);
		deployment.getComponents().add(mainAppInternalComponent);
		deployment.getComponents().add(t1_medium);
		deployment.getComponents().add(t1_micro);

		deployment.getComponentInstances().add(firstAddAppVmInstance);
		deployment.getComponentInstances().add(secondAddAppVmInstance);
		deployment.getComponentInstances().add(mainAppVmInstance);

		deployment.getRelationships().add(linkFirstAppRel);
		deployment.getRelationships().add(linkSecondAppRel);

		deployment.getRelationshipInstances().add(linkFirstAppRelInstance);
		deployment.getRelationshipInstances().add(linkSecondAppRelInstance);


		deployment.getScalableComponents().add(reg1);
		deployment.getScalableComponents().add(reg2);
		deployment.getScalableComponents().add(reg3);
	}
	*/
}
