package com.github.martinseeler.forecastio;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gag.annotation.disclaimer.WrittenWhile;
import com.google.gag.annotation.remark.Magic;
import com.google.gag.annotation.remark.RTFM;
import com.google.gag.annotation.team.Visionary;
import com.google.gag.enumeration.MagicType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * Wrapper class to execute the API requests and retrieve data.
 *
 * @author Martin Seeler
 * @since 22.11.13 - 22:01
 */
@Visionary("chasmo")
@WrittenWhile("listening to top100station")
@RTFM("https://developer.forecast.io/docs/v2")
public final class ForecastIO {

  // ===========================================================
  // Constants
  // ===========================================================

  /** Logging instance. */
  private static final Logger LOGGER = LoggerFactory.getLogger(ForecastIO.class);

  /** The base domain for API requests. */
  private static final String BASE_DOMAIN = "https://api.forecast.io/forecast";

  // ===========================================================
  // Members / Fields
  // ===========================================================

  /** The Dark Sky API key. */
  private final String apiKey;

  // ===========================================================
  // Constructors
  // ===========================================================

  /**
   * Creates a new API wrapper to request some data from the API.
   *
   * @param apiKey Your Dark Sky API key to make requests.
   */
  public ForecastIO(final String apiKey) {
    this.apiKey = apiKey;
  }

  // ===========================================================
  // Methods
  // ===========================================================

  /**
   * Performs a request to the API with the geographic coordinates of a location.
   *
   * @param latitude  The requested latitude.
   * @param longitude The requested longitude.
   *
   * @return The retrieved forecast or @{code null}, if the service is not available.
   */
  @Nullable
  @Magic(type = MagicType.WHITE)
  public Forecast getForecastFor(final double latitude, final double longitude) {
    try {
      final URL url =
          new URL(BASE_DOMAIN + '/' + apiKey + '/' + latitude + ',' + longitude + "?units=si");
      final InputStream responseStream = url.openStream();
      final ObjectMapper mapper = new ObjectMapper();
      return mapper.readValue(responseStream, Forecast.class);
    } catch (@NotNull final MalformedURLException e) {
      LOGGER.warn("There was an error building the URL for this request!", e);
      System.err.println("There was an error building the URL for this request!");
    } catch (@NotNull final JsonParseException | JsonMappingException e) {
      LOGGER.warn("There was an error while parsing the data from JSON!", e);
      System.err.println("There was an error while parsing the data from JSON!");
      e.printStackTrace();
    } catch (@NotNull final IOException e) {
      LOGGER.warn("There was an error while reading the data!", e);
      System.err.println("There was an error while reading the data!");
    }
    return null;
  }

  // ===========================================================
  // Getter & Setter
  // ===========================================================

  // ===========================================================
  // Methods for/from SuperClass/Interfaces
  // ===========================================================

  @NotNull
  @Override
  public String toString() {
    return "ForecastIO{apiKey='" + apiKey + "}";
  }

  // ===========================================================
  // Inner and Anonymous Classes
  // ===========================================================

}


@@ -2268,24 +2268,194 @@
  longitude.%0A
+   * @param unixTime Works like a time machine: Request the data as if the request was%0A   *                 done at that time. (seconds since midnight GMT on 1 Jan 1970)%0A
    *%0A   * @r
@@ -2662,16 +2662,31 @@
 ongitude
+, long unixTime
 ) %7B%0A    
@@ -2713,16 +2713,20 @@
 L url =%0A
+    
         
@@ -2799,16 +2799,32 @@
 itude + 
+',' + unixTime +
 %22?units=
@@ -3693,24 +3693,608 @@
  null;%0A  %7D%0A%0A
+  /**%0A   * Performs a request to the API with the geographic coordinates of a location.%0A   * Equal to #getForecastFor(latitude, longitude, System.currentTimeMillis() / 1000)%0A   *%0A   * @param latitude  The requested latitude.%0A   * @param longitude The requested longitude.%0A   *%0A   * @return The retrieved forecast or @%7Bcode null%7D, if the service is not available.%0A   */%0A  @Nullable%0A  @Magic(type = MagicType.WHITE)%0A  public Forecast getForecastFor(final double latitude, final double longitude) %7B%0A    return getForecastFor(latitude, longitude, System.currentTimeMillis() / 1000);%0A  %7D%0A%0A
   // =======

Support time parameter in request