/*
 * ********************************************************************************************************************
 *
 *                     :*$@@%$*:                         ;:                ;;    ;;
 *                   :@@%!  :!@@%:                       %!             ;%%@@%$ =@@@@@@@%;     @%@@@%%%%@@@@@
 *                  :@%;       :$=                       %%$$$%$$         ;$$  ;$@=   !@$
 *                  =@!                                  %!              @ $=;%   !@@@%:      !$$$$$$$$$$$$$$=
 *                  =@*                                  %!              @ $= % %@=   =%@!      %=
 *             *$%%! @@=        ;=$%%%$*:                %!              @ $= % =%%%%%%@$      *%:         =%
 *           %@@!:    !@@@%=$@@@@%!  :*@@$:              %!              @ $= % $*     ;@      @*          :%*
 *         ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
 *         $@*   ;@@@%=!:                *@*
 *         =@$    ;;;!=%@@@@=!           =@!
 *          %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2018.  北京上格云技术有限公司
 *           ;%@@$=$@@%*       *@@@$=%@@%;
 *              ::;::             ::;::                                              All rights reservad.
 *
 * ********************************************************************************************************************
 */

package com.persagy.server.http

import org.slf4j.LoggerFactory
import java.io.*
import java.net.HttpURLConnection
import java.net.URL
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse


/**
 * http工具类
 *
 * @author  PLX
 */
object HttpUntil {
    private val logger = LoggerFactory.getLogger(HttpUntil::class.java)

    /**
     * GET请求重定向
     */
    fun redirectGet(url: URL, request: HttpServletRequest, resp: HttpServletResponse) {
        logger.debug("request=$request")
        logger.debug(url.toString())
        val conn = url.openConnection() as HttpURLConnection
        conn.requestMethod = "GET"
        // 设置使用输入流
        conn.doInput = true
        // 设置有输出流
        conn.doOutput = true
        // 不使用缓冲
        conn.useCaches = false
        // 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向
        conn.instanceFollowRedirects = true
        // 设置使用标准编码格式编码参数的名-值对
        conn.setRequestProperty("Content-Type", "application/json;charset=utf-8")

        // 连接
        conn.connect()

        logger.debug("code==${conn.responseCode}：：：${HttpURLConnection.HTTP_OK}")
        // 如果正常返回
        if (HttpURLConnection.HTTP_OK == conn.responseCode) {
            resp.setHeader("Content-type", "text/html;charset=UTF-8")
            conn.inputStream.copyTo(resp.outputStream, 4096)
            conn.inputStream.close()
            resp.outputStream.close()
        }

        conn.disconnect()

        return
    } // Function postRedirect()

    /**
     * GET请求
     *
     * @param   url     请求地址
     * @return  json字符串
     */
    @Throws(Exception::class)
    fun get(url: URL) : String {
        logger.debug("url=$url")
        var result = ""
        val conn = url.openConnection() as HttpURLConnection
        conn.requestMethod = "GET"
        // 不使用缓冲
        conn.useCaches = false
        // 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向
        conn.instanceFollowRedirects = true

        // 连接
        conn.connect()

        // 如果正常返回
        if (HttpURLConnection.HTTP_OK == conn.responseCode) {
            DataInputStream(conn.inputStream)
            result = is2string(conn.inputStream)
        }

        conn.disconnect()
        logger.debug(result)
        return result
    } // Function post()

    /**
     * Get请求
     *
     * @param   url     请求地址
     * @param   clazz   生成的Java对象
     * @return  Java对象
     */
    @Throws(Exception::class)
    fun <T> get(url: URL, clazz: Class<T>): T {
        val jsonString = get(url)
        logger.debug(jsonString)
        return JacksonUtil.json2object(jsonString, clazz)
    } // Function json2object()

    /**
     * POST请求
     *
     * @param   url     请求地址
     * @return  json字符串
     */
    @Throws(Exception::class)
    fun postJson(url: URL, json: String) : String {
        logger.debug("url=$url\njson=$json")
        var result = ""
        val conn = url.openConnection() as HttpURLConnection
        conn.requestMethod = "POST"
        // 设置使用输入流
        conn.doInput = true
        // 设置有输出流
        conn.doOutput = true
        // 不使用缓冲
        conn.useCaches = false
        // 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向
        conn.instanceFollowRedirects = true
        // 设置使用标准编码格式编码参数的名-值对
        conn.setRequestProperty("Content-Type", "application/json;charset=utf-8")

        // 连接
        conn.connect()

        // 写入参数到请求中
        conn.outputStream.write(json.toByteArray(Charsets.UTF_8))
        conn.outputStream.flush()
        conn.outputStream.close()

        // 如果正常返回
        if (HttpURLConnection.HTTP_OK == conn.responseCode) {
            DataInputStream(conn.inputStream)
            result = is2string(conn.inputStream)
        }

        conn.disconnect()
        logger.debug(result)
        return result
    } // Function post()

    /**
     * POST请求
     *
     * @param   url     请求地址
     * @param   json    请求json字符串
     * @param   clazz   生成的Java对象
     * @return  Java对象
     */
    @Throws(Exception::class)
    fun <T> postJson(url: URL, json: String, clazz: Class<T>): T {
        val jsonString = postJson(url, json)
        logger.debug(jsonString)
        return JacksonUtil.json2object(jsonString, clazz)
    } // Function json2object()

    /**
     * 输入流转换为字符串
     *
     * @param   input   输入流
     * @return  字符串
     */
    private fun is2string(input: InputStream): String {
        val reader = BufferedReader(InputStreamReader(input))
        val sb = StringBuilder()
        try {
            var line: String? = reader.readLine()
            while (line != null) {
                sb.append(line + "\n")
                line = reader.readLine()
            }
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            try {
                input.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        return sb.toString()
    } // Function is2string()

} // Object HttpUntil