package ru.yandex.autotests.direct.scriptrunner.service.utils;

import com.google.gson.Gson;
import org.apache.commons.io.IOUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import ru.yandex.autotests.directapi.dbconnection.DBInfo;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class DbConfigUtils {

    private static final String DB_INFO = "db_info";
    private static final String HOST = "host";
    private static final String PORT = "port";

    private static Gson gson = new Gson();


    public static String getDbHost(String betaHost) {
        String directConfiguration = getDirectConfiguration(betaHost);

        try {
            return extractDbHost(directConfiguration);
        } catch (Exception e) {
            throw new IllegalStateException(
                    "Error while parsing DirectConfiguration response for beta " +
                            betaHost + "; response: [" + directConfiguration + "] : " + e, e);
        }
    }

    public static DBInfo getDBInfo(String betaHost) {
        String directConfiguration = getDirectConfiguration(betaHost);

        try {
            return createDBInfo(directConfiguration);
        } catch (Exception e) {
            throw new IllegalStateException(
                    "Error while creating DBInfo object from DirectConfiguration response for beta " +
                            betaHost + "; response: [" + directConfiguration + "] : " + e, e);
        }
    }


    private static String getDirectConfiguration(String betaHost) {
        try {
            String configUrl = Environments.getDirectConfigurationUrl(betaHost).toString();
            return get(configUrl);
        } catch (Exception e) {
            throw new IllegalStateException("Error while getting DB configuration for beta " +
                    betaHost + " : " + e, e);
        }
    }

    private static String extractDbHost(String directConfiguration) {
        Map container = gson.fromJson(directConfiguration, HashMap.class);
        Map dbInfo = (Map) container.get(DB_INFO);
        Iterator i = dbInfo.values().iterator();
        Object value = i.next();
        return ((Map) value).get(HOST) + ":" + ((Map) value).get(PORT);
    }

    private static DBInfo createDBInfo(String directConfiguration) {
        Map container = gson.fromJson(directConfiguration, HashMap.class);
        Map dbInfo = (Map) container.get(DB_INFO);
        return new DBInfo(dbInfo);
    }

    private static String get(String url) throws IOException {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpGet httpGet = new HttpGet(url);
            CloseableHttpResponse resp = httpclient.execute(httpGet);
            try {
                return IOUtils.toString(resp.getEntity().getContent());
            } finally {
                resp.close();
            }
        } finally {
            closeHttpClientQuietly(httpclient);
        }
    }

    private static void closeHttpClientQuietly(CloseableHttpClient httpClient) {
        try {
            httpClient.close();
        } catch (Exception e) {
            //
        }
    }
}
