package be.iminds.ilabt.jfed.lowlevel.api_wrapper.impl;

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.AbstractGeniAggregateManager;
import be.iminds.ilabt.jfed.lowlevel.api.ProtoGeniAMExtensions;
import be.iminds.ilabt.jfed.lowlevel.api_wrapper.AggregateManagerWrapper;
import be.iminds.ilabt.jfed.lowlevel.api_wrapper.ApiWrapper;
import be.iminds.ilabt.jfed.lowlevel.connection.JFedConnectionProvider;
import be.iminds.ilabt.jfed.lowlevel.connection.SfaConnection;
import be.iminds.ilabt.jfed.preferences.JFedPreferences;
import be.iminds.ilabt.jfed.util.GeniUrn;

import javax.annotation.Nonnull;
import java.util.List;

/**
 * ProtoGeniAMExtensionsWrapper
 */
public class ProtoGeniAMExtensionsWrapper extends ApiWrapper {
    @Nonnull
    protected final Server amServer;
    @Nonnull
    protected final ApiInfo.Api api;
    private final ProtoGeniAMExtensions protoGeniAMExtensions;

    public ProtoGeniAMExtensionsWrapper(@Nonnull Logger logger, @Nonnull GeniUserProvider geniUserProvider,
                                        @Nonnull JFedConnectionProvider connectionProvider, @Nonnull JFedPreferences jFedPreferences,
                                        @Nonnull Server amServer, @Nonnull ApiInfo.Api api) {
        super(logger, geniUserProvider, connectionProvider, jFedPreferences);
        this.amServer = amServer;
        this.api = api;

        this.protoGeniAMExtensions = new ProtoGeniAMExtensions(logger, jFedPreferences);
    }


    public boolean isCreateImageSupported() {
        return true;
    }

    public AggregateManagerWrapper.ImageInfo createImage(@Nonnull GeniUrn sliceUrn,
                                                         @Nonnull List<AnyCredential> sliceCredentials,
                                                         @Nonnull GeniUrn componentUrn,
                                                         @Nonnull String imageName,
                                                         boolean global, boolean updatePrepare) throws JFedException {

        AbstractGeniAggregateManager.AggregateManagerReply<ProtoGeniAMExtensions.ImageInfo> reply =
                protoGeniAMExtensions.createImage(
                        getConnection(), finalizeSliceCredentials(sliceCredentials), sliceUrn.getValue(), imageName,
                        componentUrn.getValue(), global, updatePrepare ? true : null, null);

        if (!reply.getGeniResponseCode().isSuccess())
            throw new JFedException("CreateImage call not successful", reply);

        return reply.getValue();
    }

    private SfaConnection getConnection() throws JFedException {
        GeniUser user = geniUserProvider.getLoggedInGeniUser();
        return (SfaConnection) connectionProvider.getConnectionByAuthority(user, amServer, api);
    }

    public List<? extends AggregateManagerWrapper.ImageInfo> listImages(@Nonnull List<AnyCredential> userCredentials) throws JFedException {
        GeniUser user = geniUserProvider.getLoggedInGeniUser();

        AbstractGeniAggregateManager.AggregateManagerReply<List<ProtoGeniAMExtensions.ImageInfo>> reply =
                protoGeniAMExtensions.listImages(
                        getConnection(), filterCredentials(userCredentials), user.getUserUrnString(), null);

        if (!reply.getGeniResponseCode().isSuccess())
            throw new JFedException("ListImages call not successful", reply);

        return reply.getValue();
    }

    public boolean deleteImage(@Nonnull List<AnyCredential> userCredentials, @Nonnull GeniUrn imageUrn) throws JFedException {
        GeniUser user = geniUserProvider.getLoggedInGeniUser();

        AbstractGeniAggregateManager.AggregateManagerReply<Boolean> reply =
                protoGeniAMExtensions.deleteImage(
                        getConnection(), filterCredentials(userCredentials), imageUrn.getValue(), user.getUserUrnString(), null);

        if (!reply.getGeniResponseCode().isSuccess())
            throw new JFedException("CreateImage call not successful", reply);
        if (reply.getValue() == null)
            throw new JFedException("CreateImage did not return success boolean", reply);

        return reply.getValue();
    }
}
