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

import be.iminds.ilabt.jfed.log.Logger;
import be.iminds.ilabt.jfed.lowlevel.*;
import be.iminds.ilabt.jfed.lowlevel.connection.HttpConnection;
import be.iminds.ilabt.jfed.preferences.JFedPreferences;
import be.iminds.ilabt.jfed.util.GeniUrn;
import be.iminds.ilabt.jfed.util.RFC3339Util;
import org.apache.http.entity.ContentType;
import org.json.JSONArray;
import org.json.JSONObject;

import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Date;
import java.util.Map;

/**
 * User: twalcari
 * Date: 10/29/2015
 * Time: 15:23
 */
public class SlaCollector extends RestApi {

    /**
     * @param logger          the logger to use. May be null if no logger is used.
     */
    public SlaCollector(@Nonnull Logger logger, @Nonnull JFedPreferences jFedPreferences) {
        super(logger, new ApiInfo.Api(ApiInfo.ApiName.FED4FIRE_SLA_COLLECTOR, 1), jFedPreferences);
    }

    @Override
    public String getName() {
        return getApiName();
    }

    /**
     * A human readable name for the implemented API
     *
     * @return "SLA Collector";
     */
    static public String getApiName() {
        return "SLA Collector";
    }

    @ApiMethod(order = 1, hint = "GET")
    public RestReply<String> generateUUID(@Nonnull HttpConnection con) throws JFedException {
        String javaName = "agreementslist";
        String relUrl = "agreementslist/";
        Map<String, Object> urlParams = makeMethodParameters();

        con.enablePreemptiveAuthentication(true);
        RestApi.RestReply<String> r = internalGet(con, javaName, relUrl, urlParams, urlParams);
        con.enablePreemptiveAuthentication(false);
        return r;
    }


    @ApiMethod(order = 1, hint = "POST")
    public RestReply<String> registerSLA(@Nonnull HttpConnection con,
                                         @ApiMethodParameter(name = "SLA UUID", parameterType = ApiMethodParameterType.STRING, hint = "SLA UUID")
                                         @Nonnull String slaUuid,
                                         @ApiMethodParameter(name = "Testbed", parameterType = ApiMethodParameterType.URN, hint = "Aggregate URN")
                                         @Nonnull GeniUrn aggregateUrn,
                                         @ApiMethodParameter(name = "Expiration time", parameterType = ApiMethodParameterType.DATE, hint = "Expiration time of slice")
                                         @Nonnull Date expirationDate,
                                         @ApiMethodParameter(name = "Slice URN", parameterType = ApiMethodParameterType.SLICE_URN, hint = "Slice URN")
                                         @Nonnull GeniUrn sliceUrn,
                                         @ApiMethodParameter(name = "Creator URN", parameterType = ApiMethodParameterType.USER_URN, hint = "User requesting the SLA")
                                         @Nonnull GeniUrn creatorUrn,
                                         @ApiMethodParameter(name = "List of Sliver IDs", parameterType = ApiMethodParameterType.LIST_OF_SLIVER_URN)
                                         @Nonnull Collection<GeniUrn> sliverUrns
    ) throws JFedException {
        String javaName = "agreementslist";
        String relUrl = "agreementslist/";
        Map<String, Object> urlParams = makeMethodParameters();

        JSONObject request = new JSONObject();
        request.put("SLIVER_INFO_AGGREGATE_URN", aggregateUrn.toString());
        request.put("SLIVER_INFO_EXPIRATION", RFC3339Util.dateToRFC3339String(expirationDate));
        request.put("SLIVER_INFO_SLICE_URN", sliceUrn.toString());
        request.put("SLIVER_INFO_CREATOR_URN", creatorUrn.toString());

        JSONArray sliversList = new JSONArray();
        sliverUrns.forEach(sliversList::put);
        request.put("SLIVER_INFO_URN", sliversList);
        request.put("SLIVER_INFO_SLA_ID", slaUuid);


        con.enablePreemptiveAuthentication(true);
        RestApi.RestReply<String> r =
                internalPost(con, javaName, relUrl, urlParams, urlParams, ContentType.APPLICATION_JSON, request.toString());
        con.enablePreemptiveAuthentication(false);
        return r;
    }


    @ApiMethod(order = 3, hint = "PUT")
    public RestReply<String> registerStart(@Nonnull HttpConnection con,
                                           @ApiMethodParameter(name = "SLA UUID", parameterType = ApiMethodParameterType.STRING, hint = "SLA UUID")
                                           @Nonnull String slaUuid,
                                           @ApiMethodParameter(name = "Testbed", parameterType = ApiMethodParameterType.URN, hint = "Aggregate URN")
                                           @Nonnull GeniUrn aggregateUrn) throws JFedException {
        String javaName = "enforcements";
        String relUrl = "enforcements/" + slaUuid + "/start/";

        Map<String, Object> urlParams = makeMethodParameters();
        urlParams.put("testbed", aggregateUrn.getEncodedTopLevelAuthority());

        con.enablePreemptiveAuthentication(true);
        RestApi.RestReply<String> r = internalPut(con, javaName, relUrl, urlParams, urlParams, null, null);
        con.enablePreemptiveAuthentication(false);
        return r;
    }

    @ApiMethod(order = 3, hint = "PUT")
    public RestReply<String> registerStop(@Nonnull HttpConnection con,
                                          @ApiMethodParameter(name = "SLA UUID", parameterType = ApiMethodParameterType.STRING, hint = "SLA UUID")
                                          @Nonnull String slaUuid,
                                          @ApiMethodParameter(name = "Testbed", parameterType = ApiMethodParameterType.URN, hint = "Aggregate URN")
                                          @Nonnull GeniUrn aggregateUrn) throws JFedException {
        String javaName = "enforcements";
        String relUrl = "enforcements/" + slaUuid + "/stop/";

        Map<String, Object> urlParams = makeMethodParameters();
        urlParams.put("testbed", aggregateUrn.getEncodedTopLevelAuthority());

        con.enablePreemptiveAuthentication(true);
        RestApi.RestReply<String> r = internalPut(con, javaName, relUrl, urlParams, urlParams, null, null);
        con.enablePreemptiveAuthentication(false);
        return r;
    }
}
