package eu.dnetlib.openaire.action;

import eu.dnetlib.openaire.thrift.Author;
import eu.dnetlib.openaire.thrift.Project;
import eu.dnetlib.openaire.thrift.Project4Index;
import org.apache.log4j.Logger;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import sun.net.www.protocol.http.HttpURLConnection;

import java.io.*;
import java.net.URL;
import java.util.List;

/**
 * Created by kiatrop on 26/1/2016.
 */
public class IndexUtils {

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

    public static JSONObject createJSON(String id, String source, String title, String description, String access_mode,
                                        String embargoEndDate, List<Author> authors, String url, String dcSource,
                                        String doi, List<Project> projects, List<String> subjects, List<String> concepts,
                                        String publicationDate, String publisher, String language, String category,
                                        boolean isConcept, List<Project4Index> project4Indexes, List<String> concepts4index) throws Exception {

        if (source.equals("openaire"))
            throw new IllegalArgumentException("cannot create JSON for openaire");

        //logger.info("create JSON for doi " + doi);
        //logger.info("projects " + project4Indexes);

        //if the orcid id exists
        String orcid = null;
        String hostedby = null;
        String hostedbyName = null;
        String collectedFrom = null;
        String collectedFromName = null;
        String recordIdentifier = id;

        if (source.equals("doi") && !isConcept) {
            hostedby = "openaire____::1256f046-bf1f-4afc-8b47-d0b147148b18";
            hostedbyName = "Unknown Repository";
            collectedFrom = "openaire____::crossref";
            collectedFromName = "Crossref";
            doi = id;

        } else if (source.equals("datacite")) {
            hostedby = "openaire____::1256f046-bf1f-4afc-8b47-d0b147148b18";
            hostedbyName = "Unknown Repository";
            collectedFrom = "openaire____::datacite";
            collectedFromName = "Datacite";

        } else if (source.equals("orcid")) {
            orcid = id;
            hostedby = "openaire____::1256f046-bf1f-4afc-8b47-d0b147148b18";
            hostedbyName = "Unknown Repository";
            collectedFrom = "openaire____::orcid";
            collectedFromName = "ORCID";

        } else if (source.equals("driver")) {
            hostedby = "openaire____::1256f046-bf1f-4afc-8b47-d0b147148b18";
            hostedbyName = "Unknown Repository";
            collectedFrom = "openaire____::driver";
            collectedFromName = "Digital Repository Infrastructure Vision for European Research";
        }

        JSONObject claimJSON = new JSONObject();
        String prefix = ActionUtils.getPrefix(source);
        claimJSON.put("originalId", id);
        claimJSON.put("title", title);

        JSONArray authorsJSONArray = new JSONArray();
        for (Author author: authors) {
            authorsJSONArray.add(author.getFirstName() + " " + author.getLastName());
        }
        claimJSON.put("authors", authorsJSONArray);

        claimJSON.put("publisher", publisher);
        claimJSON.put("description", description);
        claimJSON.put("language", language);

        JSONArray pidsJSONArray = new JSONArray();
        JSONObject pidJSON = null;
        if (doi != null) {
            pidJSON = new JSONObject();
            pidJSON.put("type", "doi");
            pidJSON.put("value", doi);
            pidsJSONArray.add(pidJSON);
        }
        if (orcid != null) {
            pidJSON = new JSONObject();
            pidJSON.put("type", "orcidworkid");
            pidJSON.put("value", orcid);
            pidsJSONArray.add(pidJSON);
        }
        claimJSON.put("pids", pidsJSONArray);

        claimJSON.put("licenseCode", access_mode);
        if(source.equals("crossref")) {
            claimJSON.put("resourceType", "0001");
        } else if (source.equals("datacite")) {
            claimJSON.put("resourceType", "0021");
        } else {
            claimJSON.put("resourceType", "0001");
        }

        claimJSON.put("url", url);
        claimJSON.put("collectedFromId", collectedFrom);
        claimJSON.put("hostedById", hostedby);

        JSONArray linksToProjectsJSONArray = new JSONArray();
        for (Project4Index project:project4Indexes) {
            linksToProjectsJSONArray.add(createProjectPath(project)) ;
        }
        claimJSON.put("linksToProjects",linksToProjectsJSONArray);

        JSONArray contextsJSONArray = new JSONArray();
        if(!concepts4index.isEmpty()) {
            for (String context: concepts4index) {
                contextsJSONArray.add(context); //TODO check
            }
        }
        claimJSON.put("contexts", contextsJSONArray);

        return claimJSON;
    }

    public static void feedIndex(String id, String source, String title,
                                 String description, String access_mode, String embargoEndDate,
                                 List<Author> authors, String url, String dcSource, String doi,
                                 List<Project> projects, List<String> subjects, List<String> concepts,
                                 String publicationDate, String publisher, String language, String category,
                                 boolean isConcept, List<Project4Index> project4Indexes, List<String> concepts4index,
                                 String directClaimAPIUrl) throws Exception {

        logger.info("number of projects " + project4Indexes);
        if (project4Indexes!= null) {
            logger.info("number of projects " + project4Indexes.size());
        }

        URL obj = new URL(directClaimAPIUrl);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        JSONObject claimJson = createJSON(id, source, title, description, access_mode, embargoEndDate,
                                    authors, url, dcSource, doi, projects, subjects, concepts, publicationDate,
                                    publisher, language, category, isConcept, project4Indexes, concepts4index);
        //add request header
        con.setRequestMethod("POST");
        //con.setRequestProperty("User-Agent", USER_AGENT);
        con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
        con.setRequestProperty("Content-Type", "application/json");

        logger.info("Feeding index with " + claimJson.toJSONString());
        String urlParameters = claimJson.toJSONString();

        // Send post request
        con.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(wr, "UTF-8"));
        writer.write(urlParameters);
        writer.close();
        wr.close();

        int responseCode = con.getResponseCode();
        System.out.println("\nSending 'POST' request to URL : " + url);
        System.out.println("Post parameters : " + urlParameters);
        System.out.println("Response Code : " + responseCode);

        BufferedReader in = new BufferedReader(
                new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        //print result
        System.out.println(response.toString());
    }

    private static String createProjectPath(Project4Index project) {
        if (project.getFunder().equals("EC")) {
            if(project.getAcronym() != null && !project.getAcronym().trim().isEmpty())
                return "info:eu-repo/grantAgreement/EC/"+project.getFundingStreamLevel0()+"/"
                    +project.getCode()+"/EU//"+project.getAcronym();

            return "info:eu-repo/grantAgreement/EC/"+project.getFundingStreamLevel0()+"/"
                    +project.getCode()+"/EU//"+project.getName();
        }

        if (project.getFunder().equals("WT")) {
            if(project.getAcronym() != null && !project.getAcronym().trim().isEmpty())
                return "info:eu-repo/grantAgreement/WT//"+project.getCode()+"//" + project.getAcronym();

            return "info:eu-repo/grantAgreement/WT//"+project.getCode()+project.getName();
        }

        if (project.getFunder().equals("ARC")) {
            logger.debug("name: '" + project.getName()+"'");
            logger.debug("name: '" + project.getAcronym()+"'");
            if(project.getAcronym() != null && !project.getAcronym().trim().isEmpty())
                return "info:eu-repo/grantAgreement/ARC/"+project.getFundingStreamLevel0()+"/"
                    +project.getCode()+"/AU//"+project.getAcronym();

            return "info:eu-repo/grantAgreement/ARC/"+project.getFundingStreamLevel0()+"/"
                    +project.getCode()+"/AU//"+project.getName();
        }

        if (project.getFunder().equals("NHMRC")) {
            if(project.getAcronym() != null && !project.getAcronym().trim().isEmpty())
                return "info:eu-repo/grantAgreement/NHMRC/"+project.getFundingStreamLevel0()+"/"
                        +project.getCode()+"/AU//"+project.getAcronym();

            return "info:eu-repo/grantAgreement/NHMRC/"+project.getFundingStreamLevel0()+"/"
                    +project.getCode()+"/AU//"+project.getName();
        }

        if (project.getFunder().equals("FCT")) {
            if(project.getAcronym() != null && !project.getAcronym().trim().isEmpty())
                return "info:eu-repo/grantAgreement/FCT/"+project.getFundingStreamLevel0()+"/"
                        +project.getCode()+"/PT//"+project.getAcronym();

            return "info:eu-repo/grantAgreement/FCT/"+project.getFundingStreamLevel0()+"/"
                    +project.getCode()+"/PT//"+project.getName();
        }

        return "";
    }

    public static void main(String[] args) throws IOException {

        String url = "http://beta.services.openaire.eu:8280/is/mvc/api/publications/feedObject";
        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        //add reuqest header
        con.setRequestMethod("POST");
        //con.setRequestProperty("User-Agent", USER_AGENT);
        con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
        con.setRequestProperty("Content-Type", "application/json");


        /*String urlParameters = "{\n" +
                "\"collectedFromId\": \"openaire____::crossref\",\n" +
                "\"authors\": [\"George Papastefanatos\", \"Panos Vassiliadis\", \"Alkis Simitsis\", \"Yannis Vassiliou\"],\n" +
                "\"title\": \"HECATAEUS: Regulating schema evolution\",\n" +
                "\"hostedById\": \"openaire____::1256f046-bf1f-4afc-8b47-d0b147148b18\",\n" +
                "\"licenseCode\": \"OPEN\",\n" +
                "\"pids\": [{\n" +
                "\"value\": \"10.1109\\/icde.2010.5447778\",\n" +
                "\"type\": \"doi\"\n" +
                "}],\n" +
                "\"description\": null,\n" +
                "\"originalId\": \"crossref____::817ee94bc4a0515adadb1fdaa78927f6\",\n" +
                "\"contexts\": [],\n" +
                "\"language\": null,\n" +
                "\"linksToProjects\": [\"info:eu-repo/grantAgreement/EC/FP7/283595/EU//OpenAIREplus\"],\n" +
                "\"url\": \"http:\\/\\/dx.doi.org\\/10.1109\\/icde.2010.5447778\",\n" +
                "\"resourceType\": \"0001\",\n" +
                "\"publisher\": \"Institute of Electrical & Electronics Engineers (IEEE)\"\n" +
                "}";

        String urlParameters = "{\n" +
                "\"collectedFromId\": \"openaire____::crossref\",\n" +
                "\"authors\": [\"George Papastefanatos\", \"Panos Vassiliadis\", \"Alkis Simitsis\", \"Yannis Vassiliou\"],\n" +
                " \"title\": \"â\\\\ dark bottomless Abyss, that lies under our feet, had yawned openâ\\\\\",\n" +
                "\"hostedById\": \"openaire____::1256f046-bf1f-4afc-8b47-d0b147148b18\",\n" +
                "\"licenseCode\": \"CLOSED\",\n" +
                "\"pids\": [{\n" +
                "\"value\": \"10.1007\\/s13740_012_0006_9\",\n" +
                "\"type\": \"doi\"\n" +
                "}],\n" +
                "\"description\": null,\n" +
                "\"originalId\": \"crossref____::test\",\n" +
                "\"contexts\": [\"egi::classification::natsc::infos::dmin\"], " +
                "\"language\": null, " +
                "\"linksToProjects\": [\"info:eu-repo/grantAgreement/EC/FP7/283595/EU//OpenAIREplus\"], " +
                "\"url\": \"http:\\/\\/dx.doi.org\\/10.1007\\/s13740_012_0006_9\", " +
                "\"resourceType\": \"0001\", " +
                "\"publisher\": \"Springer Science + Business Media\" " +
                "}";
*/

        String urlParameters = "{ " +
                "\"collectedFromId\": \"openaire____::crossref\", " +
                "\"authors\": [\"Agapi Dalkou\"], " +
                "\"title\": \"Η ανάπτυξη ερμηνευτικών στρατηγικών στο μάθημα της νεοελληνικής λογοτεχνίας στη δευτεροβάθμια εκπαίδευση σε περιβάλλον συνεργατικής μάθησης\", " +
                "\"hostedById\": \"openaire____::1256f046-bf1f-4afc-8b47-d0b147148b18\", " +
                "\"licenseCode\": \"CLOSED\", " +
                "\"pids\": [{ " +
                "\"value\": \"10.12681\\/eadd\\/29202\", " +
                "\"type\": \"doi\" " +
                "}], " +
                "\"description\": null, " +
                "\"originalId\": \"crossref____::cf7d85a13ac43f92431b102723d13d5a\", " +
                "\"contexts\": [\"egi\", \"egi::country::gr\"], " +
                "\"language\": null, " +
                "\"linksToProjects\": [\"info:eu-repo\\/grantAgreement\\/EC\\/FP7\\/246686\\/EU\\/\\/OPENAIRE\", \"info:eu-repo\\/grantAgreement\\/EC\\/FP7\\/288611\\/EU\\/\\/ECODRIVER\"], " +
                "\"url\": \"http:\\/\\/dx.doi.org\\/10.12681\\/eadd\\/29202\", " +
                "\"resourceType\": \"0001\", " +
                "\"publisher\": \"National Documentation Centre\"" +
                "}";

        // Send post request
        con.setDoOutput(true);
        /*DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        wr.writeBytes(urlParameters);
        wr.flush();
        wr.close();
        */

        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(wr, "UTF-8"));
        writer.write(urlParameters);
        writer.close();
        wr.close();


        int responseCode = con.getResponseCode();
        System.out.println(" Sending 'POST' request to URL : " + url);
        System.out.println("Post parameters : " + urlParameters);
        System.out.println("Response Code : " + responseCode);

        BufferedReader in = new BufferedReader(
                new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        //print result
        System.out.println(response.toString());
    }
}
