local helpers = require "spec.helpers"

for _, strategy in helpers.each_strategy() do
    describe("Plugin: force-https [#" .. strategy .. "]", function()
        local proxy_client, proxy_ssl_client

        lazy_setup(function()
            local bp = helpers.get_db_utils(strategy,
                                            {"routes", "services", "plugins"})

            local service1 = bp.services:insert{
                protocol = "http",
                host = helpers.mock_upstream_host,
                port = helpers.mock_upstream_port
            }

            local route1 = bp.routes:insert{
                protocols = {"http", "https"},
                hosts = {"force_https.test"},
                service = service1
            }

            local route2 = bp.routes:insert{
                protocols = {"http", "https"},
                hosts = {"force_https_302.test"},
                service = service1
            }

            bp.plugins:insert{route = {id = route1.id}, name = "force-https"}

            bp.plugins:insert{
                route = {id = route2.id},
                name = "force-https",
                config = {status_code = 302}
            }

            assert(helpers.start_kong({
                database = strategy,
                nginx_conf = "spec/fixtures/custom_nginx.template",
                plugins = "force-https"
            }))
        end)

        lazy_teardown(function()
            helpers.stop_kong()
        end)

        before_each(function()
            proxy_client = helpers.proxy_client()
            proxy_ssl_client = helpers.proxy_ssl_client()
        end)

        after_each(function()
            if proxy_client then
                proxy_client:close()
            end
            if proxy_ssl_client then
                proxy_ssl_client:close()
            end
        end)

        describe("HTTP", function()
            it("return 301 and https addr in response location header",
               function()
                local res = assert(proxy_client:send({
                    method = "GET",
                    path = "/status/200",
                    headers = {["Host"] = "force_https.test"}
                }))
                assert.res_status(301, res)
                assert.equal("https://force_https.test/status/200",
                             res.headers["location"])
            end)

            it("keep request parameter in response location header", function()
                local res = assert(proxy_client:send({
                    method = "GET",
                    path = "/status/200?a=b&c=d",
                    headers = {["Host"] = "force_https.test"}
                }))
                assert.res_status(301, res)
                assert.equal("https://force_https.test/status/200?a=b&c=d",
                             res.headers["location"])
            end)
        end)

        describe("HTTPS", function()
            it("directly route to backend", function()
                local res = assert(proxy_ssl_client:send({
                    method = "GET",
                    path = "/status/200",
                    headers = {["Host"] = "force_https.test"}
                }))
                assert.res_status(200, res)
            end)
        end)

        describe("HTTP With X-Forwarded-Proto Header", function()
            it("directly route to backend", function()
                local res = assert(proxy_client:send({
                    method = "GET",
                    path = "/status/200",
                    headers = {
                        ["Host"] = "force_https.test",
                        ["X-Forwarded-Proto"] = "https"
                    }
                }))
                assert.res_status(200, res)
            end)
            it("case intensitive", function()
                local res = assert(proxy_client:send({
                    method = "GET",
                    path = "/status/200",
                    headers = {
                        ["Host"] = "force_https.test",
                        ["x-forwarded-proto"] = "https"
                    }
                }))
                assert.res_status(200, res)
            end)
        end)

        describe("HTTP With Config 302", function()
            it("return 302 and https addr in response location header",
               function()
                local res = assert(proxy_client:send({
                    method = "GET",
                    path = "/status/200",
                    headers = {["Host"] = "force_https_302.test"}
                }))
                assert.res_status(302, res)
                assert.equal("https://force_https_302.test/status/200",
                             res.headers["location"])
            end)
        end)

    end)
end
