/*
 * Copyright 2015 Open Networking Laboratory
 *
 * 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.Response;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;

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 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 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} -->";

    /**
     * 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
     */
    @GET
    @Path("/")
    public Response getDefault() throws IOException {
        return getIndex();
    }

    /**
     * Get Swagger UI main index page.
     *
     * @return 200 OK
     */
    @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).build();
    }

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

    /**
     * Get Swagger UI resource.
     *
     * @return 200 OK
     */
    @GET
    @Path("{resource: .*}")
    public Response getResource(@PathParam("resource") String resource) throws IOException {
        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;
    }
}
