package com.yihu.hos.client;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpEntity;
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 org.apache.http.util.EntityUtils;

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

/**
 * @created Airhead 2016/8/1.
 */
public class BrokerServerClient {
    private static Map<String, BrokerServer> mapBrokerServer = new HashMap<>();
    private String host;

    public BrokerServerClient(String host) {
        this.host = host;
    }

    public synchronized static void addBrokerServer(BrokerServer brokerServer) {
        if (brokerServer.getEnable()) {
            mapBrokerServer.put(brokerServer.getIdentity(), brokerServer);
        } else {
            mapBrokerServer.remove(brokerServer.getIdentity());
        }
    }

    public Response invokeSync(Request request) {
        Response response = new Response();
        try {
            BrokerServer brokerServer = selectBrokerServer();
            return brokerServer.invokeSync(request);
        } catch (Exception e) {
            e.printStackTrace();

            response.setError(e);
            response.setStackTrace(e.getStackTrace().toString());
        }

        return response;

    }

    public void invokeAsync(Request request, final ResultCallback<Response> callback) {
        BrokerServer brokerServer = selectBrokerServer();
        brokerServer.invokeAsync(request, callback);
    }

    private BrokerServer selectBrokerServer() {
        if (mapBrokerServer.size() != 0) {
            return mapBrokerServer.entrySet().iterator().next().getValue();
        }

        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(host + ":10135/brokerServer");
        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(httpGet);
            if (response.getStatusLine().getStatusCode() != 200) {
                throw new IOException("Can not connect the server.");
            }

            HttpEntity entity = response.getEntity();
            String body = EntityUtils.toString(entity, "UTF-8");
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode node = objectMapper.readTree(body);
            String hostAddress = node.path("hostAddress").asText();
            String hostName = node.path("hostName").asText();
            String port = node.path("port").asText();

            BrokerServer brokerServer = new BrokerServer();
            brokerServer.setHostName(hostName);
            brokerServer.setHostAddress(hostAddress);
            brokerServer.setPort(port);
            brokerServer.setEnable(true);
            BrokerServerClient.addBrokerServer(brokerServer);
        } catch (IOException e) {
            e.printStackTrace();
            throw new EsbException(e.getMessage(), e.getCause());
        } finally {
            assert response != null;
            try {
                response.close();
                httpclient.close();
            } catch (IOException e) {
                ;
            }
        }

        return mapBrokerServer.entrySet().iterator().next().getValue();
    }
}
