package com.yihu.hos.client;

import okhttp3.*;

import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.*;

/**
 * @created Airhead 2016/8/16.
 */
class BrokerServer {
    private String hostName;
    private String hostAddress;
    private String port;
    private Boolean enable;

    public String getHostName() {
        return hostName;
    }

    void setHostName(String hostName) {
        this.hostName = hostName;
    }

    public String getHostAddress() {
        return hostAddress;
    }

    void setHostAddress(String hostAddress) {
        this.hostAddress = hostAddress;
    }

    public String getPort() {
        return port;
    }

    void setPort(String port) {
        this.port = port;
    }

    private class AsyncCall implements Callable<ClientResponse> {
        private ClientRequest clientRequest;

        AsyncCall(ClientRequest clientRequest) {
            this.clientRequest = clientRequest;
        }

        @Override
        public ClientResponse call() throws Exception {
            return invokeSync(clientRequest);
        }
    }

    Boolean getEnable() {
        return enable;
    }

    void setEnable(Boolean enable) {
        this.enable = enable;
    }

    String getIdentity() {
        return this.hostAddress + ":" + this.port;
    }

    ClientResponse invokeSync(ClientRequest clientRequest) {
        String method = clientRequest.getMethod();
        if (clientRequest.getMethod().startsWith("/")) {
            method = clientRequest.getMethod().substring(1);
        }

        ClientResponse result = new ClientResponse();
        try {
            OkHttpClient okHttpClient = new OkHttpClient();
            FormBody.Builder fromBodyBuilder = new FormBody.Builder();
            clientRequest.getArgs().forEach(fromBodyBuilder::add);
            RequestBody requestBody = fromBodyBuilder
                    .build();
            Request request = new Request.Builder().url(hostAddress + ":" + port + method)
                    .post(requestBody)
                    .build();
            Call call = okHttpClient.newCall(request);
            Response response = call.execute();
            if (!response.isSuccessful()) {
                EsbException esbException = new EsbException("Can not connect the server.");
                result.setError(esbException);
                result.setStackTrace(Arrays.toString(esbException.getStackTrace()));
                return result;
            }

            result.setResult(response.body().toString());
        } catch (IOException e) {
            e.printStackTrace();

            result.setError(e);
            result.setStackTrace(Arrays.toString(e.getStackTrace()));
        }

        return result;
    }

    void invokeAsync(ClientRequest clientRequest, final ResultCallback<ClientResponse> callback) {
        try {
            ExecutorService executorService = Executors.newCachedThreadPool();
            Future<ClientResponse> future = executorService.submit(new AsyncCall(clientRequest));
            ClientResponse clientResponse = future.get();
            if (callback != null) {
                callback.onReturn(clientResponse);
            }
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }

}
