/*
 * 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.cord.gui.model;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableList;

import java.util.List;

/**
 * Utility factory for creating and/or operating on bundles.
 */
public class BundleFactory extends JsonFactory {

    private static final String BUNDLE = "bundle";
    private static final String BUNDLES = "bundles";
    private static final String FUNCTIONS = "functions";

    private static final String BASIC_ID = "basic";
    private static final String BASIC_DISPLAY_NAME = "Basic Bundle";
    private static final String BASIC_DESCRIPTION =
            "Provides basic internet and firewall functions.";

    private static final String FAMILY_ID = "family";
    private static final String FAMILY_DISPLAY_NAME = "Family Bundle";
    private static final String FAMILY_DESCRIPTION =
            "Provides internet, firewall and parental control functions.";


    // no instantiation
    private BundleFactory() {}

    /**
     * Designates the BASIC bundle.
     */
    public static final BundleDescriptor BASIC_BUNDLE =
            new DefaultBundleDescriptor(BASIC_ID, BASIC_DISPLAY_NAME,
                                        BASIC_DESCRIPTION,
                                        XosFunctionDescriptor.INTERNET,
                                        XosFunctionDescriptor.FIREWALL);

    /**
     * Designates the FAMILY bundle.
     */
    public static final BundleDescriptor FAMILY_BUNDLE =
            new DefaultBundleDescriptor(FAMILY_ID, FAMILY_DISPLAY_NAME,
                                        FAMILY_DESCRIPTION,
                                        XosFunctionDescriptor.INTERNET,
                                        XosFunctionDescriptor.FIREWALL,
                                        XosFunctionDescriptor.URL_FILTER);

    // all bundles, in the order they should be listed in the GUI
    private static final List<BundleDescriptor> ALL_BUNDLES = ImmutableList.of(
            BASIC_BUNDLE,
            FAMILY_BUNDLE
    );

    /**
     * Returns the list of available bundles.
     *
     * @return available bundles
     */
    public static List<BundleDescriptor> availableBundles() {
        return ALL_BUNDLES;
    }

    /**
     * Returns the bundle descriptor for the given identifier.
     *
     * @param bundleId bundle identifier
     * @return bundle descriptor
     * @throws IllegalArgumentException if bundle ID is unknown
     */
    public static BundleDescriptor bundleFromId(String bundleId) {
        for (BundleDescriptor bd : ALL_BUNDLES) {
            if (bd.id().equals(bundleId)) {
                return bd;
            }
        }
        throw new IllegalArgumentException("unknown bundle: " + bundleId);
    }

    /**
     * Returns a JSON string representation of the given bundle.
     *
     * @param bundle the bundle
     * @return JSON string
     */
    public static String toJson(Bundle bundle) {
        ObjectNode root = objectNode();
        BundleDescriptor descriptor = bundle.descriptor();

        ObjectNode bnode = objectNode()
                .put(ID, descriptor.id())
                .put(NAME, descriptor.displayName())
                .put(DESC, descriptor.description());

        ArrayNode funcs = arrayNode();
        for (XosFunctionDescriptor xfd: bundle.descriptor().functions()) {
            funcs.add(XosFunctionFactory.toObjectNode(xfd));
        }
        bnode.set(FUNCTIONS, funcs);
        root.set(BUNDLE, bnode);

        ArrayNode bundles = arrayNode();
        for (BundleDescriptor bd: BundleFactory.availableBundles()) {
            ObjectNode bdnode = objectNode()
                    .put(ID, bd.id())
                    .put(NAME, bd.displayName())
                    .put(DESC, bd.description());
            bundles.add(bdnode);
        }
        root.set(BUNDLES, bundles);
        return root.toString();
    }
}
