package com.telekom.m2m.cot.restsdk.measurement;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.telekom.m2m.cot.restsdk.CloudOfThingsRestClient;
import com.telekom.m2m.cot.restsdk.util.CotSdkException;
import com.telekom.m2m.cot.restsdk.util.ExtensibleObject;
import com.telekom.m2m.cot.restsdk.util.Filter;
import com.telekom.m2m.cot.restsdk.util.GsonUtils;

import java.util.Collections;
import java.util.List;

/**
 * The API object to operate with Measurements in the platform.
 * <p>
 * Created by Patrick Steinert on 07.02.16.
 *
 * @since 0.1.0
 */
public class MeasurementApi {

    private static final String CONTENT_TYPE_MEASUREMENT = "application/vnd.com.nsn.cumulocity.measurement+json;charset=UTF-8;ver=0.9";
    private static final String ACCEPT_MEASUREMENT = "application/vnd.com.nsn.cumulocity.measurement+json;charset=UTF-8;ver=0.9";
    private static final String CONTENT_TYPE_MEASUREMENT_COLLECTION = "application/vnd.com.nsn.cumulocity.measurementCollection+json;charset=UTF-8;ver=0.9";
    private static final String ACCEPT_MEASUREMENT_COLLECTION = "application/vnd.com.nsn.cumulocity.measurementCollection+json;charset=UTF-8;ver=0.9";

    private static final String MEASUREMENTS_API = "measurement/measurements/";

    private final CloudOfThingsRestClient cloudOfThingsRestClient;
    private Gson gson = GsonUtils.createGson();

    /**
     * Internal Constructor.
     *
     * @param cloudOfThingsRestClient the configured rest client.
     */
    public MeasurementApi(CloudOfThingsRestClient cloudOfThingsRestClient) {
        this.cloudOfThingsRestClient = cloudOfThingsRestClient;
    }


    /**
     * Retrives a specific Measurement.
     *
     * @param id of the desired Measurement.
     * @return the Measurement (or null if not found).
     */
    public Measurement getMeasurement(String id) {
        String response = cloudOfThingsRestClient.getResponse(id, MEASUREMENTS_API, CONTENT_TYPE_MEASUREMENT);
        if (response == null) {
            throw new CotSdkException("Measurement not found (id='" + id + "')");
        }
        return new Measurement(gson.fromJson(response, ExtensibleObject.class));
    }

    /**
     * Stores a Measurement.
     *
     * @param measurement the measurement to create.
     * @return the created measurement with the ID.
     */
    public Measurement createMeasurement(Measurement measurement) {
        String json = gson.toJson(measurement);
        String id = cloudOfThingsRestClient.doRequestWithIdResponse(json, MEASUREMENTS_API, CONTENT_TYPE_MEASUREMENT, ACCEPT_MEASUREMENT);
        measurement.setId(id);
        return measurement;
    }

    /**
     * Stores a list of Measurements.
     *
     * @param measurements the measurements to create.
     * @return the created measurement with the ID.
     */
    public List<Measurement> createMeasurements(final List<Measurement> measurements) {

        if (measurements.isEmpty()) {
            return Collections.emptyList();
        }

        final String json = gson.toJson(createJsonObject(measurements));

        final String response = cloudOfThingsRestClient.doPostRequest(json, MEASUREMENTS_API, CONTENT_TYPE_MEASUREMENT_COLLECTION, ACCEPT_MEASUREMENT_COLLECTION);

        return gson.fromJson(response, MeasurementsHolder.class)
                .getMeasurements();
    }

    /**
     * Deletes a Measurement.
     *
     * @param measurement the Measurement to delete
     */
    public void delete(Measurement measurement) {
        cloudOfThingsRestClient.delete(measurement.getId(), MEASUREMENTS_API);
    }

    /**
     * Retrieves Measurements.
     *
     * @param resultSize size of the results (Max. 2000)
     * @return the found Measurements.
     */
    public MeasurementCollection getMeasurements(int resultSize) {
        return new MeasurementCollection(
                cloudOfThingsRestClient,
                MEASUREMENTS_API,
                gson,
                null,
                resultSize);
    }

    /**
     * Retrieves Measurements filtered by criteria.
     *
     * @param filters    filters of measurement attributes.
     * @param resultSize size of the results (Max. 2000)
     * @return the MeasurementsCollections to navigate through the results.
     * @since 0.2.0
     */
    public MeasurementCollection getMeasurements(Filter.FilterBuilder filters, int resultSize) {
        return new MeasurementCollection(
                cloudOfThingsRestClient,
                MEASUREMENTS_API,
                gson,
                filters,
                resultSize);
    }

    /**
     * Deletes a collection of Measurements by criteria.
     *
     * @param filters filters of measurement attributes.
     */
    public void deleteMeasurements(Filter.FilterBuilder filters) {
        cloudOfThingsRestClient.delete("", MEASUREMENTS_API + "?" + filters.buildFilter() + "&x=");
    }

    private JsonObject createJsonObject(final List<Measurement> measurements) {
        final JsonObject jsonObject = new JsonObject();
        jsonObject.add("measurements", listToJsonArray(measurements));
        return jsonObject;
    }

    private JsonArray listToJsonArray(final List<Measurement> measurements) {
        final JsonParser jsonParser = new JsonParser();
        return jsonParser.parse(gson.toJson(measurements)).getAsJsonArray();
    }

}

@@ -280,183 +280,37 @@
 til.
-CotSdkException;%0Aimport com.telekom.m2m.cot.restsdk.util.ExtensibleObject;%0Aimport com.telekom.m2m.cot.restsdk.util.Filter;%0Aimport com.telekom.m2m.cot.restsdk.util.GsonUtil
+*;%0A%0Aimport java.util.Array
 s;%0A
-%0A
 impo
@@ -1105,16 +1105,190 @@
 er=0.9%22;
+%0A    private static final List%3CFilterBy%3E acceptedFilters = Arrays.asList(FilterBy.BYSOURCE, FilterBy.BYDATEFROM, FilterBy.BYDATETO, FilterBy.BYFRAGMENTTYPE, FilterBy.BYTYPE);
 %0A%0A    pr
@@ -4488,32 +4488,118 @@
 t resultSize) %7B%0A
+        if(filters != null)%0A            filters.testSupportedFilter(acceptedFilters);%0A
         return n
@@ -4982,24 +4982,110 @@
  filters) %7B%0A
+        if(filters != null)%0A            filters.testSupportedFilter(acceptedFilters);%0A
         clou

add support for checking accepted filters in MeasurementApi