/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.oozie.servlet;

import org.apache.commons.io.IOUtils;
import org.apache.oozie.client.rest.JsonTags;
import org.apache.oozie.service.Services;
import org.apache.oozie.test.EmbeddedServletContainer;
import org.apache.oozie.test.XTestCase;
import org.json.JSONException;
import org.json.JSONObject;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.Callable;

public class TestJsonRestServlet extends XTestCase {

    static {
        new MyJsonRestServlet();
    }

    EmbeddedServletContainer container;

    private int invoke(String method, String resource, String queryString) throws Exception {
        return invoke(method, resource, queryString, "dummy").getResponseCode();
    }

    private HttpURLConnection invoke(String method, String resource, String queryString, String contentType) throws Exception {
        String s = container.getServletURL("/dummy");
        if (resource != null) {
            s += resource;
        }
        if (queryString != null) {
            s += "?" + queryString;
        }
        HttpURLConnection conn = (HttpURLConnection) new URL(s).openConnection();
        conn.setRequestProperty("content-type", contentType);
        conn.setRequestMethod(method);
        conn.connect();
        return conn;
    }

    private String invokeAndGetResponse(String method, String resource, String queryString, String contentType)
            throws Exception {
        String s = container.getServletURL("/dummy");
        if (resource != null) {
            s += resource;
        }
        if (queryString != null) {
            s += "?" + queryString;
        }
        HttpURLConnection conn = (HttpURLConnection) new URL(s).openConnection();
        conn.setRequestProperty("content-type", contentType);
        conn.setRequestMethod(method);
        conn.connect();
        StringBuilder sb = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),
                StandardCharsets.UTF_8));
        String line = reader.readLine();
        while (line != null) {
            sb.append(line);
            line = reader.readLine();
        }
        return sb.toString();
    }

    private void runTest(JsonRestServlet.ResourceInfo[] resourceInfo, Callable<Void> assertions) throws Exception {

        container = new EmbeddedServletContainer("test");

        Services services = new Services();
        try {
            services.init();
            MyJsonRestServlet.ACTIVE = resourceInfo;
            container.addServletEndpoint("/dummy/*", MyJsonRestServlet.class);
            container.start();
            assertions.call();
        }
        finally {
            container.stop();
            services.destroy();
        }
    }

    public void testEmptyResources() {
        try {
            MyJsonRestServlet.ACTIVE = MyJsonRestServlet.EMPTY;
            new MyJsonRestServlet();
            fail();
        }
        catch (IllegalArgumentException ex) {
            //nop
        }
    }

    public void testNoResourceNoParams() throws Exception {
        runTest(MyJsonRestServlet.NO_RESOURCE_NO_PARAMS, new Callable<Void>() {
            public Void call() throws Exception {
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", null, null));
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "", null));
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "", "a=A"));
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "/", null));
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("GET", "/hello", null));
                return null;
            }
        });
    }

    public void testParamsRequired() throws Exception {
        runTest(MyJsonRestServlet.PARAMS_REQUIRED, new Callable<Void>() {
            public Void call() throws Exception {
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "", "required=true"));
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "", "required=true&optional=true"));
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("GET", "", "optional=true"));
                return null;
            }
        });
    }

    public void testParamTypes() throws Exception {
        runTest(MyJsonRestServlet.PARAM_TYPES, new Callable<Void>() {
            public Void call() throws Exception {
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "", "boolean=true"));
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "", "boolean=false"));
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("GET", "", "boolean=x"));
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "", "integer=1"));
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("GET", "", "integer=x"));
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "", "string=a"));
                return null;
            }
        });
    }

    public void testResourceGetPostParamGet() throws Exception {
        runTest(MyJsonRestServlet.RESOURCE_GET_POST_PARAM_GET, new Callable<Void>() {
            public Void call() throws Exception {
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "", "param=true"));
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("POST", "", "param=true"));
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("GET", "", ""));
                assertEquals(HttpServletResponse.SC_OK, invoke("POST", "", ""));
                return null;
            }
        });
    }

    public void testFixedResource() throws Exception {
        runTest(MyJsonRestServlet.FIXED_RESOURCE, new Callable<Void>() {
            public Void call() throws Exception {
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("GET", "", ""));
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "/resource", ""));
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("POST", "/resource", ""));
                return null;
            }
        });
    }

    public void testWildCardResource() throws Exception {
        runTest(MyJsonRestServlet.WILDCARD_RESOURCE, new Callable<Void>() {
            public Void call() throws Exception {
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "/any", ""));
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("POST", "/any", ""));
                return null;
            }
        });
    }

    public void testInvalidResource() throws Exception {
        runTest(MyJsonRestServlet.WILDCARD_RESOURCE, new Callable<Void>() {
            public Void call() throws Exception {
                HttpURLConnection conn = invoke("GET", "/any/any", "dummy", "dummy");
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, conn.getResponseCode());
                assertEquals("E0301: Invalid resource [any/any]", conn.getResponseMessage());
                checkErrorResponse(conn, HttpServletResponse.SC_BAD_REQUEST, "E0301: Invalid resource [any/any]");
                return null;
            }
        });
    }

    public void testNoResourceWithParam() throws Exception {
        runTest(MyJsonRestServlet.WILDCARD_RESOURCE, new Callable<Void>() {
            public Void call() throws Exception {
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("PUT", "/", "action=kill"));
                return null;
            }
        });
    }

    public void testMultipleResources() throws Exception {
        runTest(MyJsonRestServlet.MULTIPLE_RESOURCES, new Callable<Void>() {
            public Void call() throws Exception {
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "/resource1", ""));
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("POST", "/resource1", ""));
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("GET", "/resource2", ""));
                assertEquals(HttpServletResponse.SC_OK, invoke("POST", "/resource2", ""));
                return null;
            }
        });
    }

    public void testMultipleResourcesNoResource() throws Exception {
        runTest(MyJsonRestServlet.MULTIPLE_RESOURCES_NO_RESOURCE, new Callable<Void>() {
            public Void call() throws Exception {
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "/resource1", ""));
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "/resource2", ""));
                assertEquals(HttpServletResponse.SC_OK, invoke("POST", "", ""));
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("POST", "/resource1", ""));
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("POST", "/resource2", ""));
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("GET", "", ""));
                return null;
            }
        });
    }

    public void testMultipleResourcesWildCard() throws Exception {
        runTest(MyJsonRestServlet.MULTIPLE_RESOURCES_WILDCARD, new Callable<Void>() {
            public Void call() throws Exception {
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "/resource1", ""));
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "/resource2", ""));
                assertEquals(HttpServletResponse.SC_OK, invoke("POST", "/any", ""));
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("POST", "/resource1", ""));
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("POST", "/resource2", ""));
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("GET", "/any", ""));
                return null;
            }
        });
    }

    public void testContentTypeJsonCron() throws Exception {
        runTest(MyJsonRestServlet.CONTENT_TYPE_JSON_CRON_TEST, new Callable<Void>() {
            public Void call() throws Exception {
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "", "json=object", "application/xml").getResponseCode());
                assertEquals(HttpServletResponse.SC_OK, invoke("GET", "", "json=object", "application/xml; param=x")
                        .getResponseCode());
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("GET", "", "json=object", "").getResponseCode());
                assertEquals(HttpServletResponse.SC_BAD_REQUEST, invoke("GET", "", "json=object", "application/json")
                        .getResponseCode());
                String response = invokeAndGetResponse("GET", "", "json=object", "application/xml");
                assertTrue(response.contains("object"));
                response = invokeAndGetResponse("GET", "", "json=array", "application/xml");
                assertTrue(response.contains("array"));
                return null;
            }
        });
    }

    private void checkErrorResponse(HttpURLConnection conn, int responseCode, String responseMessage) throws JSONException,
            IOException {
        JSONObject json = new JSONObject(IOUtils.toString(conn.getErrorStream()).trim());
        assertEquals("Error message is different.", responseMessage,
                json.getString(JsonTags.WORKFLOW_ACTION_ERROR_MESSAGE));
        assertEquals("Error code is different", responseCode,
                json.getInt(JsonTags.HTTP_STATUS_CODE));
    }

}
