/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.nlpcraft.examples.misc.darksky;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.nlpcraft.common.util.NCUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Type;
import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static java.time.temporal.ChronoUnit.DAYS;
import static java.time.temporal.ChronoUnit.SECONDS;
import static java.util.concurrent.TimeUnit.MILLISECONDS;

/**
 * Dark Sky API weather provider. See https://darksky.net/dev/docs#overview for details.
 */
public class DarkSkyService {
    // GSON response type.
    private static final Type TYPE_RESP = new TypeToken<HashMap<String, Object>>() {}.getType();

    // Access key.
    private final String key;

    // Maximum days in seconds.
    private final int maxDaysSecs;

    // HTTP client instance.
    private final CloseableHttpClient httpClient;

    // GSON instance.
    private static final Gson GSON = new Gson();

    // Date formatter.
    private static final DateTimeFormatter FMT =
        DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss").withZone(ZoneId.systemDefault());

    // Can be configured.
    private final ExecutorService pool = NCUtils.mkThreadPool(
        "darksky",
        Runtime.getRuntime().availableProcessors() * 8
    );

    /**
     *
     */
    private static final Logger log = LoggerFactory.getLogger(DarkSkyService.class);

    /**
     *
     */
    private static final ResponseHandler<String> GET_HANDLER = resp -> {
        int code = resp.getStatusLine().getStatusCode();

        if (resp.getEntity() == null)
            throw new DarkSkyException(String.format("Unexpected empty response [code=%d]", code));

        String js = EntityUtils.toString(resp.getEntity());

        if (code != 200)
            throw new DarkSkyException(String.format("Unexpected response [code=%d, text=%s]", code, js));

        return js;
    };

    /**
     * Constructor.
     *
     * @param key  Service key.
     * @param maxDays Max days configuration value.
     */
    public DarkSkyService(String key, int maxDays) {
        this.key = key;
        this.maxDaysSecs = maxDays * 24 * 60 * 60;
        this.httpClient = HttpClients.createDefault();
    }

    /**
     * Stop method.
     */
    public void stop() {
        pool.shutdown();

        try {
            pool.awaitTermination(Long.MAX_VALUE, MILLISECONDS);
        }
        catch (InterruptedException e) {
            log.error("Error stopping pool.", e);
        }
    }

    /**
     *
     * @param lat Latitude.
     * @param lon Longitude.
     * @param d Date.
     * @return
     */
    private Map<String, Object> get(double lat, double lon, Instant d) {
        return get(
            "https://api.darksky.net/forecast/" + key + '/' + lat + ',' + lon + ',' + FMT.format(d) +
                "?exclude=currently,minutely,hourly,alerts,flags?lang=en"
        );
    }

    /**
     *
     * @param url REST endpoint URL.
     * @return REST call result.
     */
    private Map<String, Object> get(String url) {
        // Ack.
        System.out.println("REST URL prepared: " + url);

        HttpGet get = new HttpGet(url);

        try {
            return GSON.fromJson(httpClient.execute(get, GET_HANDLER), TYPE_RESP);
        }
        catch (Exception e) {
            e.printStackTrace(System.err);

            throw new DarkSkyException("Unable to answer due to weather data provider error.");
        }
        finally {
            get.releaseConnection();
        }
    }

    /**
     * See https://darksky.net/dev/docs#response-format to extract fields.
     *
     * @param lat Latitude.
     * @param lon Longitude.
     * @param from From date.
     * @param to To date.
     * @return List of REST call results.
     * @throws DarkSkyException Thrown in case of any provider errors.
     */
    public List<Map<String, Object>> getTimeMachine(double lat, double lon, Instant from, Instant to) throws DarkSkyException {
        assert from != null;
        assert to != null;

        log.debug("DarkSky time machine API call [lat={}, lon={}, from={}, to={}]", lat, lon, from, to);

        if (Duration.between(from, to).get(SECONDS) > maxDaysSecs)
            throw new DarkSkyException(String.format("Request period is too long [from=%s, to=%s]", from, to));

        long durMs = to.toEpochMilli() - from.toEpochMilli();

        int n = (int) (durMs / 86400000 + (durMs % 86400000 == 0 ? 0 : 1));

        return IntStream.range(0, n).
            mapToObj(shift -> pool.submit(() -> Pair.of(shift, get(lat, lon, from.plus(shift, DAYS))))).
            map(p -> {
                try {
                    return p.get();
                }
                catch (ExecutionException | InterruptedException e) {
                    throw new DarkSkyException("Error executing weather request.", e);
                }
            }).
            sorted(Comparator.comparing(Pair::getLeft)).
            map(Pair::getRight).
            collect(Collectors.toList());
    }

    /**
     * See https://darksky.net/dev/docs#response-format to extract fields.
     *
     * @param lat Latitude.
     * @param lon Longitude.
     * @return REST call result.
     * @throws DarkSkyException Thrown in case of any provider errors.
     */
    public Map<String, Object> getCurrent(double lat, double lon) throws DarkSkyException {
        return get("https://api.darksky.net/forecast/" + key + '/' + lat + ',' + lon +
            "?exclude=minutely,hourly,daily,alerts,flags?lang=en");
    }
}
