/*
 * Copyright 2015-present Open Networking Foundation
 *
 * Licensed 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.onosproject.rest.resources;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.rest.AbstractInjectionResource;
import org.onosproject.rest.ApiDocService;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.net.URI;
import java.net.URISyntaxException;

import static com.google.common.collect.ImmutableList.of;
import static com.google.common.io.ByteStreams.toByteArray;
import static javax.ws.rs.core.MediaType.*;
import static javax.ws.rs.core.Response.temporaryRedirect;
import static org.onlab.util.Tools.nullIsNotFound;

/**
 * REST API documentation.
 */
@Path("docs")
public class ApiDocResource extends AbstractInjectionResource {

    private static final String CONTENT_TYPE = "Content-Type";
    private static final String CONTENT_SECURITY_POLICY = "Content-Security-Policy";
    private static final String FRAME_ANCESTORS_NONE = "frame-ancestors 'none'";
    private static final String STYLESHEET = "text/css";
    private static final String SCRIPT = "text/javascript";
    private static final String DOCS = "/docs/";

    private static final String INJECT_START = "<!-- {API-START} -->";
    private static final String INJECT_END = "<!-- {API-END} -->";

    @Context
    private UriInfo uriInfo;

    /**
     * Get all registered REST API docs.
     * Returns array of all registered API docs.
     *
     * @return 200 OK
     */
    @GET
    @Path("apis")
    public Response getApiList() {
        ObjectNode root = mapper().createObjectNode();
        ArrayNode apis = newArray(root, "apis");
        get(ApiDocService.class).getDocProviders().forEach(p -> apis.add(p.name()));
        return ok(root.toString()).build();
    }

    /**
     * Get Swagger UI JSON.
     *
     * @param key REST API web context
     * @return 200 OK
     */
    @GET
    @Path("apis/{key: .*?}/swagger.json")
    public Response getApi(@PathParam("key") String key) {
        String k = key.startsWith("/") ? key : "/" + key;
        InputStream stream = nullIsNotFound(get(ApiDocService.class).getDocProvider(k),
                                            "REST API not found for " + k).docs();
        return ok(nullIsNotFound(stream, "REST API docs not found for " + k))
                .header(CONTENT_TYPE, APPLICATION_JSON).build();
    }

    /**
     * Get REST API model schema.
     *
     * @param key REST API web context
     * @return 200 OK
     */
    @GET
    @Path("apis/{key: .*?}/model.json")
    public Response getApiModel(@PathParam("name") String key) {
        String k = key.startsWith("/") ? key : "/" + key;
        InputStream stream = nullIsNotFound(get(ApiDocService.class).getDocProvider(k),
                                            "REST API not found for " + k).model();
        return ok(nullIsNotFound(stream, "REST API model not found for " + k))
                .header(CONTENT_TYPE, APPLICATION_JSON).build();
    }

    /**
     * Get Swagger UI main index page.
     *
     * @return 200 OK
     * @throws IOException if unable to get index resource
     * @throws URISyntaxException if unable to create redirect URI
     */
    @GET
    public Response getDefault() throws IOException, URISyntaxException {
        return uriInfo.getPath().endsWith("/") ? getIndex() :
                temporaryRedirect(new URI(uriInfo.getPath() + "/")).build();
    }

    /**
     * Get Swagger UI main index page.
     *
     * @return 200 OK
     * @throws IOException if unable to get index resource
     */
    @GET
    @Path("index.html")
    public Response getIndex() throws IOException {
        InputStream stream = getClass().getClassLoader().getResourceAsStream(DOCS + "index.html");
        nullIsNotFound(stream, "index.html not found");

        String index = new String(toByteArray(stream));

        int p1s = split(index, 0, INJECT_START);
        int p1e = split(index, p1s, INJECT_END);
        int p2s = split(index, p1e, null);

        StreamEnumeration streams =
                new StreamEnumeration(of(stream(index, 0, p1s),
                                         includeOptions(get(ApiDocService.class)),
                                         stream(index, p1e, p2s)));

        return ok(new SequenceInputStream(streams))
                .header(CONTENT_TYPE, TEXT_HTML)
                .header(CONTENT_SECURITY_POLICY, FRAME_ANCESTORS_NONE).build();
    }

    private InputStream includeOptions(ApiDocService service) {
        StringBuilder sb = new StringBuilder();
        service.getDocProviders().forEach(p -> {
            sb.append("<option value=\"").append(p.key()).append("\"")
                    .append("/onos/v1".equals(p.key()) ? " selected>" : ">")
                    .append(p.name())
                    .append("</option>");
        });
        return new ByteArrayInputStream(sb.toString().getBytes());
    }

    /**
     * Get Swagger UI resource.
     *
     * @param resource path of the resource
     * @return 200 OK
     * @throws IOException if unable to get named resource
     */
    @GET
    @Path("{resource: .*}")
    public Response getResource(@PathParam("resource") String resource) throws IOException {
        if ("".equals(resource)) {
            return getIndex();
        }
        InputStream stream = getClass().getClassLoader().getResourceAsStream(DOCS + resource);
        return ok(nullIsNotFound(stream, resource + " not found"))
                .header(CONTENT_TYPE, contentType(resource)).build();
    }

    static String contentType(String resource) {
        return resource.endsWith(".html") ? TEXT_HTML :
                resource.endsWith(".css") ? STYLESHEET :
                        resource.endsWith(".js") ? SCRIPT :
                                APPLICATION_OCTET_STREAM;
    }
}
