package edu.unl.cse.bohn;

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLConnection;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

public class ImportData {

    public static final String FILENAME = "apikeys.json";

    protected final String protocol;
    protected final String host;
    protected final String path;
    protected final String apiKey;

    @SuppressWarnings("unused")
    public static List<String> readFile(String filename) throws IOException {
        List<String> data = new LinkedList<>();
        BufferedReader bufferedReader;
        bufferedReader = new BufferedReader(new FileReader(filename));
        while (bufferedReader.ready()) {
            data.add(bufferedReader.readLine());
        }
        return data;
    }

    public ImportData(String apiKeyName, int year, int day) {
        String apiKey;
        protocol = "https";
        host = "adventofcode.com";
        path = "/" + year + "/day/" + day + "/input";
        try {
            apiKey = getApiKey(apiKeyName);
        } catch (IOException ioException) {
            System.err.println("Could not retrieve API key: " + ioException.getMessage());
            apiKey = null;
        }
        this.apiKey = apiKey;
    }

    protected String getApiKey(String apiKeyName) throws IOException {
        JSONObject apiKeyJson;
        try (InputStreamReader inputStreamReader = new InputStreamReader(
                Objects.requireNonNull(ImportData.class.getClassLoader().getResourceAsStream(FILENAME)))) {
            apiKeyJson = (JSONObject)new JSONParser().parse(inputStreamReader);
        } catch (NullPointerException nullPointerException) {
            FileNotFoundException newException = new FileNotFoundException("File " + FILENAME + " not found.");
            newException.initCause(nullPointerException);
            throw newException;
        } catch (ParseException parseException) {
            throw new IOException("Error while parsing file " + FILENAME + ".", parseException);
        }
        if (!apiKeyJson.containsKey(apiKeyName)) {
            System.err.println("WARNING! Could not locate API key named " + apiKeyName + " in file " + FILENAME + ".");
        }
        String apiKey = apiKeyJson.get(apiKeyName).toString();
        if (apiKey.equals("")) {
            System.err.println("WARNING! API key named " + apiKeyName + " in file " + FILENAME + " is blank.");
        }
        return apiKey;
    }

    public List<String> importData() throws IOException {
        List<String> data = new LinkedList<>();
        BufferedReader bufferedReader;
        try {
            URLConnection connection = new URI(protocol, host, path, null).toURL().openConnection();
            connection.setRequestProperty("Cookie", "session=" + apiKey);
            bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        } catch (URISyntaxException | MalformedURLException originalException) {
            throw new IOException("Could not retrieve usable data from " + host + ".", originalException);
        }
        while (bufferedReader.ready()) {
            data.add(bufferedReader.readLine());
        }
        return data;
    }
}