package de.jeyp91.openligadb;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

/**
 *
 */
public class OpenLigaDBConnector {

    private final String OPENLIGADB_API_URL = "http://www.openligadb.de/api/";

    public OpenLigaDBConnector() {}

    public OpenLigaDBMatch getMatchDataOfSingleMatch(int id) {
        String url = OPENLIGADB_API_URL + "getmatchdata/" + id;
        JSONObject matchAsJson = getDataAsJSONObject(url);
        return new OpenLigaDBMatch(matchAsJson);
    }

    public ArrayList<OpenLigaDBMatch> getMatchDataOfMatchday(int season, String league, int matchday) {

        String url = OPENLIGADB_API_URL + "getmatchdata/" + league + "/" + (season - 1) + "/" + matchday;

        JSONArray matches = getDataAsJSONArray(url);
        ArrayList<OpenLigaDBMatch> matchesList = new ArrayList<>();

        for(Object match: matches) {
            matchesList.add(new OpenLigaDBMatch((JSONObject) match));
        }

        return matchesList;
    }

    public ArrayList<OpenLigaDBMatch> getMatchDataOfCurrentMatchday(String league) {

        String url = OPENLIGADB_API_URL + "getmatchdata/" + league;

        JSONArray matches = getDataAsJSONArray(url);
        ArrayList<OpenLigaDBMatch> matchesList = new ArrayList<>();

        for(Object match: matches) {
            matchesList.add(new OpenLigaDBMatch((JSONObject) match));
        }

        return matchesList;
    }

    public OpenLigaDBMatch getMatchDataByMatchId(int id) {
        String url = OPENLIGADB_API_URL + "getmatchdata/" + id;
        JSONObject match = getDataAsJSONObject(url);
        return new OpenLigaDBMatch(match);
    }

    private JSONArray getDataAsJSONArray(String requestUrl) {

        String rawData = getRawData(requestUrl);
        JSONParser parser = new JSONParser();
        JSONArray data = null;
        try {
            data = (JSONArray) parser.parse(rawData);
        } catch (ParseException e) {
            /* TODO */
            e.printStackTrace();
        }
        return data;
    }

    private JSONObject getDataAsJSONObject(String requestUrl) {

        String rawData = getRawData(requestUrl);
        JSONParser parser = new JSONParser();
        JSONObject data = null;
        try {
            data = (JSONObject) parser.parse(rawData);
        } catch (ParseException e) {
            /* TODO */
            e.printStackTrace();
        }
        return data;
    }

    private String getRawData(String requestUrl) {

        HttpClient client = HttpClientBuilder.create().build();
        HttpGet request = new HttpGet(requestUrl);

        // add request header
        request.addHeader("Content-Type", "application/json");

        HttpResponse response = null;
        try {
            response = client.execute(request);
        } catch (ClientProtocolException e) {
            /* TODO */
            e.printStackTrace();
        } catch (IOException e) {
            /* TODO */
            e.printStackTrace();
        }


        BufferedReader rd = null;
        try {
            rd = new BufferedReader(
                    new InputStreamReader(response.getEntity().getContent())
            );
        } catch (IOException e) {
            /* TODO */
            e.printStackTrace();
        }

        StringBuilder result = new StringBuilder();
        String line = "";
        while (true) {
            try {
                line = rd.readLine();
            } catch (IOException e) {
                /* TODO */
                e.printStackTrace();
            }

            // Stop reading if last line was found.
            if (line  == null) break;

            result.append(line);
        }
        return result.toString();
    }
}