package com.yihu.hos.client;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;

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 ClientResponse invokeSync(ClientRequest clientRequest) {
        ClientResponse clientResponse = new ClientResponse();
        try {
            BrokerServer brokerServer = selectBrokerServer();
            return brokerServer.invokeSync(clientRequest);
        } catch (Exception e) {
            e.printStackTrace();

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

        return clientResponse;

    }

    public void invokeAsync(ClientRequest clientRequest, final ResultCallback<ClientResponse> callback) {
        BrokerServer brokerServer = selectBrokerServer();
        brokerServer.invokeAsync(clientRequest, callback);
    }

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

        try {
            OkHttpClient okHttpClient = new OkHttpClient();
            Request request = new Request.Builder().url(host + ":10135/brokerServer").build();
            Call call = okHttpClient.newCall(request);
            Response response = call.execute();
            if (!response.isSuccessful()) {
                throw new IOException("Can not connect the server.");
            }

            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode node = objectMapper.readTree(response.body().toString());
            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());
        }

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