package com.yihu.hos.arbiter.services;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.hos.arbiter.models.BrokerServer;
import com.yihu.hos.arbiter.models.ServiceFlow;
import org.apache.http.Consts;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

/**
 * @created Airhead 2016/8/16.
 */
@Service("serviceFlowService")
public class ServiceFlowService {
    private static final Logger logger = LogManager.getLogger(BrokerServerService.class);
    @Autowired
    private BrokerServerService brokerServerService;

    public void save(String serviceFlow) {
    }

    public String get(String serviceName) {
        return null;
    }

    public String put(String serviceName, String ClientInfo) {
        return null;
    }

    public void trigger(String msg) {
        System.out.println(msg);
        BrokerServer brokerServer = brokerServerService.get();
        if (brokerServer == null) {
            logger.trace("can not find a valid broker server.");
            return;
        }

        ObjectMapper objectMapper = new ObjectMapper();
        try {
            ServiceFlow serviceFlow = objectMapper.readValue(msg, ServiceFlow.class);
            List<NameValuePair> nameValuePairList = new ArrayList<>();
            nameValuePairList.add(new BasicNameValuePair("serviceFlow", serviceFlow.getServiceFlow()));
            nameValuePairList.add(new BasicNameValuePair("packageName", serviceFlow.getPackageName()));
            nameValuePairList.add(new BasicNameValuePair("className", serviceFlow.getClassName()));
            nameValuePairList.add(new BasicNameValuePair("path", serviceFlow.getPath()));

            CloseableHttpClient httpclient = HttpClients.createDefault();
            switch (serviceFlow.getEvent()) {
                case "processorAdded": {
                    HttpPost httpPost = new HttpPost(brokerServer.getURL() + "/esb/processor");
                    httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairList, Consts.UTF_8));
                    CloseableHttpResponse response = httpclient.execute(httpPost);
                    response.close();
                    break;
                }

                case "processorDataChanged": {
                    HttpPut httpPut = new HttpPut(brokerServer.getURL() + "/esb/processor");
                    httpPut.setEntity(new UrlEncodedFormEntity(nameValuePairList, Consts.UTF_8));
                    CloseableHttpResponse response = httpclient.execute(httpPut);
                    response.close();
                    break;
                }

                case "routeDefineAdded": {
                    HttpPost httpPost = new HttpPost(brokerServer.getURL() + "/esb/processor");
                    httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairList, Consts.UTF_8));
                    CloseableHttpResponse response = httpclient.execute(httpPost);
                    response.close();
                    break;
                }

                case "routeDefineChanged": {
                    HttpPut httpPut = new HttpPut(brokerServer.getURL() + "/esb/route");
                    httpPut.setEntity(new UrlEncodedFormEntity(nameValuePairList, Consts.UTF_8));
                    CloseableHttpResponse response = httpclient.execute(httpPut);
                    response.close();
                    break;
                }
                case "routeDefineDelete": {
                    try {
                        URI uri = new URIBuilder()
                                .setScheme("http")
                                .setHost(brokerServer.getHostAddress() + ":" + brokerServer.getPort())
                                .setPath("/route")
                                .setParameter("serviceFlow", serviceFlow.getServiceFlow())
                                .setParameter("packageName", serviceFlow.getPackageName())
                                .setParameter("className", serviceFlow.getClassName())
                                .setParameter("path", serviceFlow.getPath())
                                .build();

                        HttpDelete httpDelete = new HttpDelete(uri);
                        CloseableHttpResponse response = httpclient.execute(httpDelete);
                        response.close();
                    } catch (URISyntaxException e) {
                        e.printStackTrace();
                    }


                    break;
                }
                default:
                    break;
            }


        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
