package brooklyn.location.jclouds;

import static org.testng.Assert.assertNotNull;

import java.io.File;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;

import org.jclouds.Constants;
import org.jclouds.ContextBuilder;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
import org.jclouds.scriptbuilder.domain.Statement;
import org.jclouds.scriptbuilder.domain.Statements;
import org.jclouds.scriptbuilder.statements.login.AdminAccess;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.Test;

import brooklyn.config.BrooklynProperties;
import brooklyn.util.text.Identifiers;

import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
import com.google.common.io.Files;

public class StandaloneJcloudsTest {

    // FIXME Why do this?
    // Were we seeing bugs in jclouds for which this was easier to debug and report
    // Is it because testProvisioningVmWithCustomUsername is disabled and not working?
    
    public static final Logger LOG = LoggerFactory.getLogger(StandaloneJcloudsTest.class);
    
    static BrooklynProperties globals = BrooklynProperties.Factory.newDefault();

    String identity = globals.getFirst("brooklyn.jclouds.aws-ec2.identity");
    String credential = globals.getFirst("brooklyn.jclouds.aws-ec2.credential");
    
    @Test(groups={"WIP","Live"})
    public void createVm() {
        String groupId = "mygroup-"+System.getProperty("user.name")+"-"+UUID.randomUUID().toString();
 
        Properties properties = new Properties();
        properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, Boolean.toString(true));
        properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, Boolean.toString(true));
        // handy to list all images... but very slow!
//        properties.setProperty(AWSEC2Constants.PROPERTY_EC2_AMI_QUERY, "state=available;image-type=machine");

        ComputeServiceContext computeServiceContext = ContextBuilder.newBuilder("aws-ec2").
                modules(Arrays.asList(new SshjSshClientModule(), new SLF4JLoggingModule())).
                credentials(identity, credential).
                overrides(properties).
                build(ComputeServiceContext.class);
        
        final ComputeService computeService = computeServiceContext.getComputeService();
        
        NodeMetadata node = null;
        try {
            LOG.info("Creating VM for "+identity);

            TemplateBuilder templateBuilder = computeService.templateBuilder();
            templateBuilder.locationId("eu-west-1");
            
            Template template = templateBuilder.build();
            Set<? extends NodeMetadata> nodes = computeService.createNodesInGroup(groupId, 1, template);
            node = Iterables.getOnlyElement(nodes, null);
            if (node == null) throw new IllegalStateException("No nodes returned");

            assertNotNull(node.getOperatingSystem());

            Credentials nodeCredentials = node.getCredentials();
            final LoginCredentials expectedCredentials = LoginCredentials.fromCredentials(nodeCredentials);
            
            LOG.info("Started VM, waiting for it to be sshable");
            boolean reachable = false;
            for (int i=0; i<120; i++) {
                try {
                    Statement statement = Statements.newStatementList(Statements.exec("date"));
                    ExecResponse response = computeService.runScriptOnNode(node.getId(), statement,
                            RunScriptOptions.Builder.overrideLoginCredentials(expectedCredentials));
                    if (response.getExitStatus() == 0) {
                        LOG.info("ssh 'date' succeeded");
                        reachable = true;
                        break;
                    }
                    LOG.info("ssh 'date' failed, exit "+response.getExitStatus()+", but still in retry loop");
                } catch (Exception e) {
                    if (i<120)
                        LOG.info("ssh 'date' failed, but still in retry loop: "+e);
                    else {
                        LOG.error("ssh 'date' failed after timeout: "+e, e);
                        Throwables.propagate(e);
                    }
                }
                Thread.sleep(1000);
            }
        
            if (!reachable) {
                throw new IllegalStateException("SSH failed, never reachable");
            }

        } catch (RunNodesException e) {
            if (e.getNodeErrors().size() > 0) {
                node = Iterables.get(e.getNodeErrors().keySet(), 0);
            }
            LOG.error("Failed to start VM: "+e, e);
            throw Throwables.propagate(e);
        } catch (Exception e) {
            LOG.error("Failed to start VM: "+e, e);
            throw Throwables.propagate(e);
        } finally {
            LOG.info("Now destroying VM: "+node);
            computeService.destroyNode( node.getId() );

            computeService.getContext().close();
        }
        
    }
    
    @Test(groups={"WIP","Live"})
    public void createVmWithAdminUser() {
        String groupId = "mygroup-"+System.getProperty("user.name")+"-"+UUID.randomUUID().toString();
 
        Properties properties = new Properties();
        properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, Boolean.toString(true));
        properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, Boolean.toString(true));

        ComputeServiceContext computeServiceContext = ContextBuilder.newBuilder("aws-ec2").
                modules(Arrays.asList(new SshjSshClientModule(), new SLF4JLoggingModule())).
                credentials(identity, credential).
                overrides(properties).
                build(ComputeServiceContext.class);
        
        final ComputeService computeService = computeServiceContext.getComputeService();
        
        NodeMetadata node = null;
        try {
            LOG.info("Creating VM for "+identity);
            String myPubKey = Files.toString(new File(System.getProperty("user.home")+"/.ssh/aws-id_rsa.pub"), Charset.defaultCharset());
            String myPrivKey = Files.toString(new File(System.getProperty("user.home")+"/.ssh/aws-id_rsa"), Charset.defaultCharset());

            TemplateBuilder templateBuilder = computeService.templateBuilder();
            templateBuilder.locationId("us-east-1");
            TemplateOptions opts = new TemplateOptions();
            
//            templateBuilder.imageId("us-east-1/ami-2342a94a");  //rightscale
            // either use above, or below
            templateBuilder.imageId("us-east-1/ami-f95cf390");  //private one (to test when user isn't autodetected)
            opts.overrideLoginUser("ec2-user");
            
            AdminAccess.Builder adminBuilder = AdminAccess.builder().
                    adminUsername("bob").
                    grantSudoToAdminUser(true).
                    authorizeAdminPublicKey(true).adminPublicKey(myPubKey).
                    // items below aren't wanted but values for some are required otherwise AdminAccess uses all defaults
                    lockSsh(true).adminPassword(Identifiers.makeRandomId(12)).
                    resetLoginPassword(false).loginPassword(Identifiers.makeRandomId(12)).
                    installAdminPrivateKey(false).adminPrivateKey("ignored");
            opts.runScript(adminBuilder.build());
            
            templateBuilder.options(opts);
            
            Template template = templateBuilder.build();
            Set<? extends NodeMetadata> nodes = computeService.createNodesInGroup(groupId, 1, template);
            node = Iterables.getOnlyElement(nodes, null);
            if (node == null) throw new IllegalStateException("No nodes returned");

            LOG.info("Started VM, waiting for it to be sshable on "+node.getPublicAddresses());
            final LoginCredentials crds =
//                    node.getCredentials();
                    LoginCredentials.builder().user("bob").privateKey(myPrivKey).build();
            boolean reachable = false;
            for (int i=0; i<120; i++) {
                try {
                    Statement statement = Statements.newStatementList(Statements.exec("date"));
                    ExecResponse response = computeService.runScriptOnNode(node.getId(), statement,
                            RunScriptOptions.Builder.overrideLoginCredentials(crds));
                    if (response.getExitStatus() == 0) {
                        LOG.info("ssh 'date' succeeded");
                        reachable = true;
                        break;
                    }
                    LOG.info("ssh 'date' failed, exit "+response.getExitStatus()+", but still in retry loop");
                } catch (Exception e) {
                    if (i<120)
                        LOG.info("ssh 'date' failed, but still in retry loop: "+e);
                    else {
                        LOG.error("ssh 'date' failed after timeout: "+e, e); 
                        Throwables.propagate(e);
                    }
                }
                Thread.sleep(1000);
            }
        
            if (!reachable) {
                throw new IllegalStateException("SSH failed, never reachable");
            }
            
        } catch (RunNodesException e) {
            if (e.getNodeErrors().size() > 0) {
                node = Iterables.get(e.getNodeErrors().keySet(), 0);
            }
            LOG.error("Failed to start VM: "+e, e);
            throw Throwables.propagate(e);
        } catch (Exception e) {
            LOG.error("Failed to start VM: "+e, e);
            throw Throwables.propagate(e);
        } finally {
            LOG.info("Now destroying VM: "+node);
            computeService.destroyNode( node.getId() );

            computeService.getContext().close();
        }
        
    }

}
