package be.iminds.ilabt.jfed.examples;

import be.iminds.ilabt.jfed.*;
import be.iminds.ilabt.jfed.fedmon.webapi.service.json.Server;
import be.iminds.ilabt.jfed.log.Logger;
import be.iminds.ilabt.jfed.lowlevel.*;
import be.iminds.ilabt.jfed.lowlevel.api_wrapper.AggregateManagerWrapper;
import be.iminds.ilabt.jfed.lowlevel.api_wrapper.UserAndSliceApiWrapper;
import be.iminds.ilabt.jfed.lowlevel.api_wrapper.impl.AutomaticAggregateManagerWrapper;
import be.iminds.ilabt.jfed.lowlevel.api_wrapper.impl.AutomaticUserAndSliceApiWrapper;
import be.iminds.ilabt.jfed.lowlevel.authority.AuthorityFinder;

import be.iminds.ilabt.jfed.lowlevel.connection.JFedConnectionProvider;
import be.iminds.ilabt.jfed.preferences.JFedPreferences;
import be.iminds.ilabt.jfed.util.IOUtils;
import com.google.inject.Guice;
import com.google.inject.Injector;

import java.io.File;
import java.util.List;
import java.util.Objects;

public class ClientWrapperApiExample {
    public static void main(String[] args) throws Exception {
        try {
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////

            Logger logger = new Logger();

            ////////////////////////////////////////////////////////////////////////////////////////////////////////////

            File defaultPemKeyCertFile =
                    new File(System.getProperty("user.home") + File.separator + ".ssl" + File.separator + "geni_cert.pem");
            String pemKeyCertFilename =
                    IOUtils.askCommandLineInput("PEM key and certificate filename (default: \"" + defaultPemKeyCertFile.getPath() + "\")");
            char[] pass = IOUtils.askCommandLinePassword("Key password (if any)");
            if (pemKeyCertFilename == null || pemKeyCertFilename.equals(""))
                pemKeyCertFilename = defaultPemKeyCertFile.getPath();


            //////////////////////////////////////////// Setup user ////////////////////////////////////////////////////

            SimpleGeniUser user = new SimpleGeniUser(null, null, IOUtils.fileToString(pemKeyCertFilename),
                    (pass.length == 0) ? null : pass, defaultPemKeyCertFile, defaultPemKeyCertFile);

            ////////////////////////////////////////// Get target test authority ///////////////////////////////////////

            Injector injector = Guice.createInjector(new BasicTestbedInfoModule(), new JFedWebApiClientModule(), new DirectUserModule(user), new PreLoginCoreModule(), new PostLoginCoreModule(), new CorePreferencesModule());
            TestbedInfoSource testbedInfoSource =  injector.getInstance(TestbedInfoSource.class);
            AuthorityFinder authorityFinder =  injector.getInstance(AuthorityFinder.class);

            GeniUser loggedInUser = injector.getInstance(GeniUser.class);
            if (loggedInUser != null) {
                System.out.println("You are logged in as user: " + loggedInUser.getUserUrn());
                if (loggedInUser.getUserAuthorityServer() != null) {
                    System.out.println("             on authority: " + loggedInUser.getUserAuthorityServer().getDefaultComponentManagerUrn());
                    if (loggedInUser.getUserAuthorityServer().getServices() == null || loggedInUser.getUserAuthorityServer().getServices().isEmpty()) {
                        System.err.println("ERROR: there are no URLs known for your user authority! (services="+loggedInUser.getUserAuthorityServer().getServices()+")");
                        System.exit(1);
                    }
                    if (!Objects.equals(loggedInUser.getUserUrnString(), user.getUserUrnString())) {
                        System.err.println("WARNING: the user you are now logged in with ("+loggedInUser.getUserUrnString()+"), " +
                                "does not match the user you started login with ("+user.getUserUrnString()+"). " +
                                "(this should not happen)");
                    }
                } else {
                    System.err.println("ERROR: the authority of your user was not found!");
                    System.exit(1);
                }
            } else {
                System.err.println("ERROR: null user!");
                System.exit(1);
            }

            Server wall = authorityFinder.findByUrn("urn:publicid:IDN+wall2.ilabt.iminds.be+authority+cm", AuthorityFinder.Purpose.CREATE_SLIVER);

            ///////////////////////////////////////////// Call any GetVersion /////////////////////////////////////////

            JFedConnectionProvider conPool = injector.getInstance(JFedConnectionProvider.class);
            JFedPreferences jFedPreferences = injector.getInstance(JFedPreferences.class);
            AggregateManagerWrapper amWrapper = injector.getInstance(AutomaticAggregateManagerWrapper.AutomaticAggregateManagerWrapperFactory.class).
                    create(wall);
            UserAndSliceApiWrapper credWrapper = injector.getInstance(AutomaticUserAndSliceApiWrapper.AutomaticUserAndSliceApiWrapperFactory.class).
                    create();

            amWrapper.getVersion();

            ///////////////////// Get a user credential. /////////////////////////

            List<AnyCredential> creds = credWrapper.getUserCredentials(logger, user.getUserUrn());
            for (AnyCredential cred : creds)
                System.out.println("\n\ncredential:\n" + cred.getCredentialXml().substring(0,
                        cred.getCredentialXml().length() > 300 ? 300 : cred.getCredentialXml().length()) + "...\n");

            //////////////////////////////////////////// Call ListResources ///////////////////////////////////////

            String rspec = amWrapper.listResources(creds, true/*available*/);

            if (rspec != null)
                System.out.println("\n\nAdvertisement RSpec: " + rspec);
            else
                System.out.println("\n\nListResources failed.");

            ////////////////////////////////////////////////////////////////////////////////////////////////////////////

            System.exit(0);
        } catch (JFedException e) {
            System.err.println("JFedException: " + e);
            e.printStackTrace();
            if (e.getXmlRpcResult() != null) {
                System.err.println("HTTP request:\n" + e.getXmlRpcResult().getRequestHttpContent());
                System.err.println("\nHTTP response:\n" + e.getXmlRpcResult().getResultHttpContent());
                System.err.println("\nXMLRPC request:\n" + e.getXmlRpcResult().getRequestXmlRpcString());
                System.err.println("\nXMLRPC response:\n" + e.getXmlRpcResult().getResultXmlRpcString());
            }
            System.exit(1);
        }
    }
}
