package cz.senslog.connector.push.theros;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import cz.senslog.connector.model.api.GeoJsonModel;
import cz.senslog.connector.push.api.ConnectorPusher;
import cz.senslog.connector.tools.http.HttpClient;
import cz.senslog.connector.tools.http.HttpRequest;
import cz.senslog.connector.tools.http.HttpResponse;
import cz.senslog.connector.tools.http.URLBuilder;
import cz.senslog.connector.tools.json.BasicJson;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.List;

import static cz.senslog.connector.tools.http.HttpContentType.APPLICATION_JSON;
import static cz.senslog.connector.tools.http.HttpHeader.*;

public class TherosPusher implements ConnectorPusher<GeoJsonModel> {

    private static final Logger logger = LogManager.getLogger(TherosPusher.class);

    private final TherosConfig config;
    private final HttpClient httpClient;
    private final AuthService authService;

    public TherosPusher(TherosConfig config, AuthService authService, HttpClient httpClient) {
        this.config = config;
        this.authService = authService;
        this.httpClient = httpClient;

    }

    @Override
    public void init() {
        if (authService.authenticate()) {
            logger.info("Authentication was successful.");
        } else {
            throw logger.throwing(new RuntimeException("Authentication failed."));
        }
    }

    @Override
    public void push(GeoJsonModel model) {

        if (model == null || model.isEmpty()) {
            logger.warn("Nothing to push."); return;
        }

        List<JsonElement> geoFeatures = model.getGeoJson().getAsJsonArray("features").asList();
        geoFeatures.forEach(feature -> feature.getAsJsonObject().get("properties").getAsJsonObject()
                        .addProperty("lotNumber", "X1234345")
                );

        AuthorizationToken token = authService.getAuthorizationToken();
        HttpRequest request = HttpRequest.newBuilder().POST()
                .url(URLBuilder.newBuilder(config.getBaseUrl(), "observations").build())
                .header(CONTENT_TYPE, APPLICATION_JSON)
                .header(AUTHORIZATION, String.format("%s %s", token.getTokenType(), token.getAccessToken()))
                .body(model.getGeoJson().toString())
                .build();

        HttpResponse response = httpClient.send(request);

        if (response.isOk()) {
            JsonObject geoJson = BasicJson.jsonToObject(response.getBody(), JsonObject.class);
            int uploadedFeatures = geoJson.get("features").getAsJsonArray().size();
            logger.info("Send telemetries {}/{} from {} to {}.", geoFeatures.size(), uploadedFeatures, model.getFrom(), model.getTo());
        } else {
            logger.error("Can not send telemetries from {} to {}.", model.getFrom(), model.getTo());
            logger.error(response.getBody());
        }
    }
}
