package be.iminds.ilabt.jfed.lowlevel.api.test;

import be.iminds.ilabt.jfed.log.Logger;
import be.iminds.ilabt.jfed.lowlevel.GeniUserProvider;
import be.iminds.ilabt.jfed.lowlevel.JFedException;
import be.iminds.ilabt.jfed.lowlevel.TestbedInfoSource;
import be.iminds.ilabt.jfed.lowlevel.connection.JFedConnectionProvider;
import be.iminds.ilabt.jfed.preferences.JFedPreferences;
import be.iminds.ilabt.jfed.util.TargetAuthority;

import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;

/**
 * TestAggregateManager2
 */
public class TestAggregateManager2NitosHack extends TestAggregateManager2 {
    @Inject
    public TestAggregateManager2NitosHack(Logger logger, TargetAuthority testedAuthority, GeniUserProvider geniUserProvider, JFedConnectionProvider connectionProvider, TestbedInfoSource testbedInfoSource, JFedPreferences jFedPreferences) {
        super(logger, testedAuthority, geniUserProvider, connectionProvider, testbedInfoSource, jFedPreferences);
    }

    public String getTestDescription() {
        return "Many Aggregate Manager (Geni AM API v2) Tests. 2 slices and a sliver will be created during the tests. " +
                "The sliver will be deleted. " +
                "This will not test ListResources when requesting an advertisement request " +
                "(takes too long, use TestAggregateManager2AllListResources). " +
                "\n\n" +
                "IMPORTANT: This is an extension of the normal test, that does some specific hacks to test the not yet fully functional Nitos Broker";
    }


    @Override
    public List<String> getOptConfKeys() {
        List<String> res = new ArrayList<>();
        /* fixed_ssh_private_key_file and fixed_ssh_public_key_file option:
              There are 3 cases:
                  option not specified: use randomly generated key that is different each time
                  option specified, with private key file specified: use public and private key from files (public key can be read from PEM certificate)
                  option specified, with private key file specified, AND this file is the same file for both and is a user login file (key+cert file): use public and private key from file.

         */
        res.add("fixed_ssh_public_key_file"); //needed if fixed_ssh_private_key_file is specified (file containing PEM x509certificate is also allowed)
        res.add("fixed_ssh_private_key_file"); //needed if fixed_ssh_public_key_file is specified
        res.add("fixed_ssh_private_key_password"); //may be null,even if fixed_ssh_private_key_file is not (in case no password is needed)

        res.add("create_slice_if_not_exists");
        res.add("reuse_slice_if_exists");
        res.add("fixed_slice_name"); //uses this slice name. If not specified, will generate a slice name automatically
        res.add("disable_compliance_tests"); //test only for bare functionality, do not do extra checks
        res.add("disable_slice_cleanup"); //no deleteSliver call
        CommonAMTest.addOptionsForFixedRspec(res);

        //speaks for not yet ready to be tested for this hack

//        //speaksfor and delegation support
//        res.add("credentialType"); //regular, speaksFor or delegation
//        res.add("speaksForOptionNames"); //options: "geni_speaks_for", "geni_experimenter_urn" or any other, or comma seperated list of options
//        res.add("passwordFilename2");
//        res.add("userUrn2");
//        res.add("pemKeyAndCertFilename2");
//        res.add("userAuthorityUrn2");

        //proxy info is fixed for this hack
//
//        //proxy for ssh connections
//        res.add("sshProxyHostName");
//        res.add("sshProxyHostKey");
//        res.add("sshProxyHostPort");
//        res.add("sshProxyUsername"); //default: same username as logged in user (same as "$USER"). Some limited variable substitution is done:
//             // - $NODE: username for target node
//             // - $USER: logged in user name (last part of user URN)
//             // - $SLICE: slice name (last part of slice URN)
//        res.add("sshProxyKeySource"); //valid choices:
//             // - user (take SSH keys from user login cert and key)
//             // - node (use the same SSH keys as the one to login to the actual target node, these are typically generated by NodeLoginTester, unless fixed_ssh_public_key_file says otherwise)
//             // - file: take from file name specified in sshProxyPrivateKeyFile and sshProxyPublicKeyFile option (not yet implemented)

        return res;
    }

    @Test(hardDepends = {"testCreateSliver"}, softDepends = {"testSliverStatusExistingSliver",
                                                             "testListResourcesExistingSliver"}, groups = {
            "createsliver", "nodelogin"})
    public void testCreatedSliverBecomesReady() throws JFedException {
//           //Currently on Nitos, it won't ever get ready. So will will wait a small time, and then fail. No need to wait 20 minutes.
//           note("Nitos HACK: wait 30 seconds (hardcoded) and then conclude sliver is never going to be ready (not even checked, hardcoded).");
//           try {
//               Thread.sleep(30000 /*ms*/);
//           } catch (InterruptedException e) { /* Ignore*/ }
//
//           throw new RuntimeException("Sliver did not become ready on Nitos.   (not waited long enough and not checked: this is a hardcoded hack for Nitos)");


        note("Nitos HACK: Sliver will never become ready. So instead of checking, wait 30 seconds (hardcoded) and then continue.");
        try {
            Thread.sleep(30000 /*ms*/);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


//    //run if createSliver was successful, even if sliver never becomes ready.
////    @Test(hardDepends = {"checkManifestOnceSliverIsReady"}, groups = {"nodelogin"} )
//    @Test(hardDepends = {"testCreateSliver"}, softDepends = {"testCreatedSliverBecomesReady",
//                                                             "checkManifestOnceSliverIsReady"}, groups = {"nodelogin"})
//    public void testNodeLogin() throws JFedException, IOException {
//        assert nodeLoginTester != null;
//
//        //setup fixed proxy for nitos
//        String sshProxyHostName = "nitlab.inf.uth.gr";
//        int sshProxyHostPort = 22;
//        String sshProxyHostKey =
//                "nitlab.inf.uth.gr ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCq06yhwdFwp6dN/CYUyIqfQ9/pKPz" +
//                        "LC52rQk/aLrjEuo10RvSw6wYLUARZB2KbPpXr/HWba5Pyv5OZLD/hpW9cRCiH9kM4u45zIXrmlnkDAfAYh6BOV03Pi0YK325ws+FTC" +
//                        "BK+cSVlrrJaQS3Ymp+fgICq+V0faETNMc1aRX4cEwK/vohZKTmBFWwKwUnaWQRcyh56l5RFyTajRr8IUW1v8slNUVlBsCPIpIM0ETL" +
//                        "YbI0NeWISUgpcIB0lmFozjI5GjlhL7zgpeKgfqikfHwvhFxoJkU2rHvl9SWFuZtH/WpzM13TFaDEvI1ITI1I0WY7C9EePYC8vXZFsS" +
//                        "i0TJi1n";
//
//
//
//        //first attempt was using username, but that didn't work
////        String sshProxyUsername = user.getUserUrn().getResourceName(); //username
//
//        //it used to be slice name, but that has changed
////        String sshProxyUsername = sliceSliver.urn.getResourceName(); //slice name as username
//
//        String sshProxyUsername =
//                    user.getUserUrn().getTopLevelAuthority() +
//                    ".user." +
//                    user.getUserUrn().getResourceName();
//
//
//        note("Using fixed proxy for nitos: "+sshProxyHostName+":"+sshProxyHostPort);
//        note("Username for nitos proxy: "+sshProxyUsername);
//
//        note("Using user certificate node private key as proxy private key.");
//        SshKeyInfo sshProxyKeyInfo = new BasicSshKeyInfo(
//                nodeLoginTester.getSshKeyHelper().getSshPublicKey(),
//                nodeLoginTester.getSshKeyHelper().getSshPrivateKey());
//
//        JFedConnection.SshProxyInfo sshProxyInfo = new JFedConnection.SshProxyInfo(
//                sshProxyHostName,
//                sshProxyHostPort,
//                sshProxyUsername,
//                sshProxyKeyInfo,
//                sshProxyHostKey,
//                false/*limitName*/);
//        note("Configured SSH proxy for SSH login test: " + sshProxyInfo);
//        nodeLoginTester.setSshProxy(sshProxyInfo);
//
//
//        ///////////////////////////////////////////////////////////////////////
//        //// WARNING: for current testing, login to proxy instead of node! ////
//        ///////////////////////////////////////////////////////////////////////
////        nodeLoginTester.setSshInfo(sshProxyUsername, sshProxyHostName, sshProxyHostPort);
//        nodeLoginTester.setSshInfo(sshProxyUsername, "127.0.0.1", sshProxyHostPort);
//        note("Not testing omf and machine access: Only trying to connect to proxy itself (127.0.0.1) over proxy proxy.");
//
//        nodeLoginTester.testNodeLogin(!beLessStrict);
//    }

}
