/*
 * Copyright 2015-present 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.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.net.config.Config;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.config.SubjectFactory;
import org.onosproject.rest.AbstractWebResource;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.InputStream;
import java.util.Set;

import static org.onlab.util.Tools.emptyIsNotFound;
import static org.onlab.util.Tools.nullIsNotFound;

/**
 * Manage network configurations.
 */
@Path("network/configuration")
public class NetworkConfigWebResource extends AbstractWebResource {

    private String subjectClassNotFoundErrorString(String subjectClassKey) {
        return "Config for '" + subjectClassKey + "' not found";
    }

    private String subjectNotFoundErrorString(String subjectClassKey,
                                              String subjectKey) {
        return "Config for '"
                + subjectClassKey + "/" + subjectKey
                + "' not found";
    }

    private String configKeyNotFoundErrorString(String subjectClassKey,
                                                String subjectKey,
                                                String configKey) {
        return "Config for '"
                + subjectClassKey + "/" + subjectKey + "/" + configKey
                + "' not found";
    }

    /**
     * Get entire network configuration base.
     *
     * @return network configuration JSON
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @SuppressWarnings("unchecked")
    public Response download() {
        NetworkConfigService service = get(NetworkConfigService.class);
        ObjectNode root = mapper().createObjectNode();
        service.getSubjectClasses().forEach(sc -> {
            SubjectFactory subjectFactory = service.getSubjectFactory(sc);
            produceJson(service, newObject(root, subjectFactory.subjectClassKey()),
                        subjectFactory, sc);
        });
        return ok(root).build();
    }

    /**
     * Get all network configuration for a subject class.
     *
     * @param subjectClassKey subject class key
     * @return network configuration JSON
     */
    @GET
    @Path("{subjectClassKey}")
    @Produces(MediaType.APPLICATION_JSON)
    @SuppressWarnings("unchecked")
    public Response download(@PathParam("subjectClassKey") String subjectClassKey) {
        NetworkConfigService service = get(NetworkConfigService.class);
        ObjectNode root = mapper().createObjectNode();
        SubjectFactory subjectFactory =
                nullIsNotFound(service.getSubjectFactory(subjectClassKey),
                               subjectClassNotFoundErrorString(subjectClassKey));
        produceJson(service, root, subjectFactory, subjectFactory.subjectClass());
        return ok(root).build();
    }

    /**
     * Get all network configuration for a subjectKey.
     *
     * @param subjectClassKey subjectKey class key
     * @param subjectKey      subjectKey key
     * @return network configuration JSON
     */
    @GET
    @Path("{subjectClassKey}/{subjectKey}")
    @Produces(MediaType.APPLICATION_JSON)
    @SuppressWarnings("unchecked")
    public Response download(@PathParam("subjectClassKey") String subjectClassKey,
                             @PathParam("subjectKey") String subjectKey) {
        NetworkConfigService service = get(NetworkConfigService.class);
        ObjectNode root = mapper().createObjectNode();
        SubjectFactory subjectFactory =
                nullIsNotFound(service.getSubjectFactory(subjectClassKey),
                               subjectClassNotFoundErrorString(subjectClassKey));
        produceSubjectJson(service, root, subjectFactory.createSubject(subjectKey),
                           true,
                           subjectNotFoundErrorString(subjectClassKey, subjectKey));
        return ok(root).build();
    }

    /**
     * Get specific network configuration for a subjectKey.
     *
     * @param subjectClassKey subjectKey class key
     * @param subjectKey      subjectKey key
     * @param configKey       configuration class key
     * @return network configuration JSON
     */
    @GET
    @Path("{subjectClassKey}/{subjectKey}/{configKey}")
    @Produces(MediaType.APPLICATION_JSON)
    @SuppressWarnings("unchecked")
    public Response download(@PathParam("subjectClassKey") String subjectClassKey,
                             @PathParam("subjectKey") String subjectKey,
                             @PathParam("configKey") String configKey) {
        NetworkConfigService service = get(NetworkConfigService.class);

        Object subject =
                nullIsNotFound(service.getSubjectFactory(subjectClassKey)
                                       .createSubject(subjectKey),
                                        subjectNotFoundErrorString(subjectClassKey, subjectKey));

        Class configClass =
                nullIsNotFound(service.getConfigClass(subjectClassKey, configKey),
                               configKeyNotFoundErrorString(subjectClassKey, subjectKey, configKey));
        Config config =
                nullIsNotFound(service.getConfig(subject, configClass),
                               configKeyNotFoundErrorString(subjectClassKey,
                                                            subjectKey,
                                                            configKey));
        return ok(config.node()).build();
    }

    @SuppressWarnings("unchecked")
    private void produceJson(NetworkConfigService service, ObjectNode node,
                             SubjectFactory subjectFactory, Class subjectClass) {
        service.getSubjects(subjectClass).forEach(s ->
            produceSubjectJson(service, newObject(node, subjectFactory.subjectKey(s)), s, false, ""));
    }

    private void produceSubjectJson(NetworkConfigService service, ObjectNode node,
                                    Object subject,
                                    boolean emptyIsError,
                                    String emptyErrorMessage) {
        Set<? extends Config<Object>> configs = service.getConfigs(subject);
        if (emptyIsError) {
            // caller wants an empty set to be a 404
            configs = emptyIsNotFound(configs, emptyErrorMessage);
        }
        configs.forEach(c -> node.set(c.key(), c.node()));
    }


    /**
     * Upload bulk network configuration.
     *
     * @param request network configuration JSON rooted at the top node
     * @return empty response
     * @throws IOException if unable to parse the request
     */
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @SuppressWarnings("unchecked")
    public Response upload(InputStream request) throws IOException {
        NetworkConfigService service = get(NetworkConfigService.class);
        ObjectNode root = (ObjectNode) mapper().readTree(request);
        root.fieldNames()
                .forEachRemaining(sk -> consumeJson(service, (ObjectNode) root.path(sk),
                                                    service.getSubjectFactory(sk)));
        return Response.ok().build();
    }

    /**
     * Upload multiple network configurations for a subject class.
     *
     * @param subjectClassKey subject class key
     * @param request         network configuration JSON rooted at the top node
     * @return empty response
     * @throws IOException if unable to parse the request
     */
    @POST
    @Path("{subjectClassKey}")
    @Consumes(MediaType.APPLICATION_JSON)
    @SuppressWarnings("unchecked")
    public Response upload(@PathParam("subjectClassKey") String subjectClassKey,
                           InputStream request) throws IOException {
        NetworkConfigService service = get(NetworkConfigService.class);
        ObjectNode root = (ObjectNode) mapper().readTree(request);
        consumeJson(service, root, service.getSubjectFactory(subjectClassKey));
        return Response.ok().build();
    }

    /**
     * Upload mutliple network configurations for a subjectKey.
     *
     * @param subjectClassKey subjectKey class key
     * @param subjectKey      subjectKey key
     * @param request         network configuration JSON rooted at the top node
     * @return empty response
     * @throws IOException if unable to parse the request
     */
    @POST
    @Path("{subjectClassKey}/{subjectKey}")
    @Consumes(MediaType.APPLICATION_JSON)
    @SuppressWarnings("unchecked")
    public Response upload(@PathParam("subjectClassKey") String subjectClassKey,
                           @PathParam("subjectKey") String subjectKey,
                           InputStream request) throws IOException {
        NetworkConfigService service = get(NetworkConfigService.class);
        ObjectNode root = (ObjectNode) mapper().readTree(request);
        consumeSubjectJson(service, root,
                           service.getSubjectFactory(subjectClassKey).createSubject(subjectKey),
                           subjectClassKey);
        return Response.ok().build();
    }

    /**
     * Upload specific network configuration for a subjectKey.
     *
     * @param subjectClassKey subjectKey class key
     * @param subjectKey      subjectKey key
     * @param configKey       configuration class key
     * @param request         network configuration JSON rooted at the top node
     * @return empty response
     * @throws IOException if unable to parse the request
     */
    @POST
    @Path("{subjectClassKey}/{subjectKey}/{configKey}")
    @Consumes(MediaType.APPLICATION_JSON)
    @SuppressWarnings("unchecked")
    public Response upload(@PathParam("subjectClassKey") String subjectClassKey,
                           @PathParam("subjectKey") String subjectKey,
                           @PathParam("configKey") String configKey,
                           InputStream request) throws IOException {
        NetworkConfigService service = get(NetworkConfigService.class);
        JsonNode root = mapper().readTree(request);
        service.applyConfig(subjectClassKey,
                            service.getSubjectFactory(subjectClassKey).createSubject(subjectKey),
                            configKey, root);
        return Response.ok().build();
    }

    private void consumeJson(NetworkConfigService service, ObjectNode classNode,
                             SubjectFactory subjectFactory) {
        classNode.fieldNames().forEachRemaining(s ->
            consumeSubjectJson(service, (ObjectNode) classNode.path(s),
                               subjectFactory.createSubject(s),
                               subjectFactory.subjectClassKey()));
    }

    private void consumeSubjectJson(NetworkConfigService service,
                                    ObjectNode subjectNode, Object subject,
                                    String subjectClassKey) {
        subjectNode.fieldNames().forEachRemaining(configKey ->
            service.applyConfig(subjectClassKey, subject, configKey, subjectNode.path(configKey)));
    }


    // FIXME: Refactor to allow queued configs to be removed

    /**
     * Clear entire network configuration base.
     *
     * @return empty response
     */
    @DELETE
    @SuppressWarnings("unchecked")
    public Response delete() {
        NetworkConfigService service = get(NetworkConfigService.class);
        service.getSubjectClasses()
                .forEach(subjectClass -> service.getSubjects(subjectClass)
                        .forEach(subject -> service.getConfigs(subject)
                                .forEach(config -> service.removeConfig(subject, config.getClass()))));
        return Response.ok().build();
    }

    /**
     * Clear all network configurations for a subject class.
     *
     * @param subjectClassKey subject class key
     */
    @DELETE
    @Path("{subjectClassKey}")
    @SuppressWarnings("unchecked")
    public void delete(@PathParam("subjectClassKey") String subjectClassKey) {
        NetworkConfigService service = get(NetworkConfigService.class);
        service.getSubjects(service.getSubjectFactory(subjectClassKey).subjectClass())
                .forEach(subject -> service.getConfigs(subject)
                        .forEach(config -> service.removeConfig(subject, config.getClass())));
    }

    /**
     * Clear all network configurations for a subjectKey.
     *
     * @param subjectClassKey subjectKey class key
     * @param subjectKey      subjectKey key
     */
    @DELETE
    @Path("{subjectClassKey}/{subjectKey}")
    @SuppressWarnings("unchecked")
    public void delete(@PathParam("subjectClassKey") String subjectClassKey,
                           @PathParam("subjectKey") String subjectKey) {
        NetworkConfigService service = get(NetworkConfigService.class);
        Object s = service.getSubjectFactory(subjectClassKey).createSubject(subjectKey);
        service.getConfigs(s).forEach(c -> service.removeConfig(s, c.getClass()));
    }

    /**
     * Clear specific network configuration for a subjectKey.
     *
     * @param subjectClassKey subjectKey class key
     * @param subjectKey      subjectKey key
     * @param configKey       configuration class key
     */
    @DELETE
    @Path("{subjectClassKey}/{subjectKey}/{configKey}")
    @SuppressWarnings("unchecked")
    public void delete(@PathParam("subjectClassKey") String subjectClassKey,
                           @PathParam("subjectKey") String subjectKey,
                           @PathParam("configKey") String configKey) {
        NetworkConfigService service = get(NetworkConfigService.class);
        service.removeConfig(service.getSubjectFactory(subjectClassKey).createSubject(subjectKey),
                             service.getConfigClass(subjectClassKey, configKey));
    }

}
