package org.zstack.core.rest;

import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.zstack.header.message.APIMessage;
import org.zstack.header.message.APISyncCallMessage;
import org.zstack.header.rest.RESTApiFacade;
import org.zstack.header.rest.RESTConstant;
import org.zstack.header.rest.RESTFacade;
import org.zstack.header.rest.RestAPIResponse;
import org.zstack.utils.Utils;
import org.zstack.utils.gson.JSONObjectUtil;
import org.zstack.utils.logging.CLogger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@Controller
public class RESTApiController {
    private static final CLogger logger = Utils.getLogger(RESTApiController.class);
    @Autowired
    private RESTApiFacade restApi;
    @Autowired
    private RESTFacade restf;

    @RequestMapping(value = RESTConstant.REST_API_RESULT + "{uuid}", method = {RequestMethod.GET, RequestMethod.PUT})
    public void queryResult(@PathVariable String uuid, HttpServletResponse rsp) throws IOException {
        try {
            RestAPIResponse apiRsp = restApi.getResult(uuid);
            if (apiRsp == null) {
                rsp.sendError(HttpStatus.SC_NOT_FOUND, String.format("No api result[uuid:%s] found", uuid));
                return;
            }

            PrintWriter writer = rsp.getWriter();
            String res = JSONObjectUtil.toJsonString(apiRsp);
            rsp.setStatus(HttpStatus.SC_OK);
            writer.write(res);
        } catch (Throwable t) {
            logger.warn(t.getMessage(), t);
            rsp.sendError(HttpStatus.SC_INTERNAL_SERVER_ERROR, t.getMessage());
        }
    }

    private String handleByMessageType(String body) {
        APIMessage amsg = null;
        try {
            amsg = (APIMessage) RESTApiDecoder.loads(body);
        } catch (Throwable t) {
            return t.getMessage();
        }

        RestAPIResponse rsp = null;
        if (amsg instanceof APISyncCallMessage) {
            rsp = restApi.call(amsg);
        } else {
            rsp = restApi.send(amsg);
        }
        return JSONObjectUtil.toJsonString(rsp);
    }

    @RequestMapping(value = RESTConstant.REST_API_CALL, method = {RequestMethod.POST, RequestMethod.PUT})
    public void post(HttpServletRequest request, HttpServletResponse response) throws IOException {
        HttpEntity<String> entity = restf.httpServletRequestToHttpEntity(request);
        try {
            String ret = handleByMessageType(entity.getBody());
            response.setStatus(HttpStatus.SC_OK);
            PrintWriter writer = response.getWriter();
            writer.write(ret);
        } catch (Throwable t) {
            StringBuilder sb = new StringBuilder(String.format("Error when calling %s", request.getRequestURI()));
            sb.append(String.format("\nheaders: %s", entity.getHeaders().toString()));
            sb.append(String.format("\nbody: %s", entity.getBody()));
            sb.append(String.format("\nexception message: %s", t.getMessage()));
            logger.debug(sb.toString(), t);
            response.sendError(HttpStatus.SC_INTERNAL_SERVER_ERROR, sb.toString());
        }
    }
}

@@ -1639,32 +1639,78 @@
 ;%0A            %7D%0A
+            rsp.setCharacterEncoding(%22UTF-8%22);
 %0A            Pri
@@ -2947,32 +2947,84 @@
 pStatus.SC_OK);%0A
+            response.setCharacterEncoding(%22UTF-8%22);%0A
             Prin

fix #1043 enable cli to support ch