package be.iminds.ilabt.jfed;

import be.iminds.ilabt.jfed.fedmon.webapi.service.json.Server;
import be.iminds.ilabt.jfed.lowlevel.AnyCredential;
import be.iminds.ilabt.jfed.lowlevel.GeniUser;
import be.iminds.ilabt.jfed.lowlevel.GeniUserProvider;
import be.iminds.ilabt.jfed.lowlevel.SimpleGeniUserWithSpeaksFor;
import be.iminds.ilabt.jfed.lowlevel.user.GeniUserFactory;
import be.iminds.ilabt.jfed.lowlevel.userloginmodel.InvalidLoginException;
import be.iminds.ilabt.jfed.util.GeniUrn;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Named;
import javax.inject.Singleton;
import java.io.File;
import java.util.List;

/**
 * BaseCliModule
 */
public class KeyCertFileUserModule extends AbstractModule {
    private final static Logger LOG = LoggerFactory.getLogger(KeyCertFileUserModule.class);

    private final String keyCertContent;
    private final char[] keyPass;
    private final File certificateKeyFile;
    private final File privateKeyFile;
    private final List<AnyCredential> speaksForCredentials;

    public KeyCertFileUserModule(String keyCertContent, char[] keyPass, File certificateKeyFile, File privateKeyFile) {
        this.keyCertContent = keyCertContent;
        this.keyPass = keyPass;
        this.certificateKeyFile = certificateKeyFile;
        this.privateKeyFile = privateKeyFile;
        this.speaksForCredentials = null;
    }
    public KeyCertFileUserModule(String keyCertContent, char[] keyPass, File certificateKeyFile, File privateKeyFile, List<AnyCredential> speaksForCredentials) {
        this.keyCertContent = keyCertContent;
        this.keyPass = keyPass;
        this.certificateKeyFile = certificateKeyFile;
        this.privateKeyFile = privateKeyFile;
        this.speaksForCredentials = speaksForCredentials == null || speaksForCredentials.isEmpty() ? null : speaksForCredentials;
    }

    @Provides
    @Singleton
    public GeniUser getGeniUser(GeniUserFactory geniUserFactory) {
        try {
            if (speaksForCredentials == null) {
                return geniUserFactory.createGeniUser(keyCertContent, keyPass, certificateKeyFile, privateKeyFile);
            } else {
                return geniUserFactory.createGeniUser(keyCertContent, keyPass, certificateKeyFile, privateKeyFile, speaksForCredentials);
            }
        } catch (InvalidLoginException e) {
            LOG.error("Could not login the user", e);
            return null;
        } catch (SimpleGeniUserWithSpeaksFor.InvalidSpeaksForException e) {
            LOG.error("The provided speaksfor credential was invalid", e);
            return null;
        }
    }

    @Provides
    @Singleton
    @Named("userUrn")
    public GeniUrn getUserUrn(GeniUser geniUser) {
        if (geniUser != null)
            return geniUser.getUserUrn();
        else
            return null;
    }

    @Provides
    @Named("userServer")
    public Server provideGeniUserServer(GeniUser geniUser) {
        if (geniUser != null)
            return geniUser.getUserAuthorityServer();
        else
            return null;
    }

    @Provides
    public GeniUserProvider provideGeniUserProvider(final GeniUser geniUser) {
        return new GeniUserProvider() {
            @Override
            public GeniUser getLoggedInGeniUser() {
                return geniUser;
            }

            @Override
            public boolean isUserLoggedIn() {
                return geniUser != null;
            }
        };
    }

    @Override
    protected void configure() {

    }
}
