/*
 * Copyright 2018-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.odtn.cli.impl;

import static org.onosproject.odtn.utils.YangToolUtil.toCharSequence;
import static org.onosproject.odtn.utils.YangToolUtil.toCompositeData;
import static org.onosproject.odtn.utils.YangToolUtil.toDocument;
import static org.onosproject.odtn.utils.YangToolUtil.toResourceData;
import static org.onosproject.odtn.utils.YangToolUtil.toXmlCompositeStream;
import static org.slf4j.LoggerFactory.getLogger;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.apache.karaf.shell.commands.Option;
import org.onlab.util.XmlString;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cli.net.DeviceIdCompleter;
import org.onosproject.config.DynamicConfigService;
import org.onosproject.net.DeviceId;
import org.onosproject.net.device.DeviceService;
import org.onosproject.netconf.NetconfController;
import org.onosproject.netconf.NetconfDevice;
import org.onosproject.netconf.NetconfException;
import org.onosproject.odtn.behaviour.ConfigurableTransceiver;
import org.onosproject.odtn.behaviour.PlainTransceiver;
import org.onosproject.odtn.utils.openconfig.OpticalChannel;
import org.onosproject.odtn.utils.openconfig.Transceiver;
import org.onosproject.yang.model.DataNode;
import org.onosproject.yang.model.ResourceId;
import org.slf4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.google.common.collect.Lists;
import com.google.common.io.CharSource;


@Command(scope = "onos", name = "odtn-manual-test",
         description = "ODTN manual test command")
public class OdtnManualTestCommand extends AbstractShellCommand {

    private static final Logger log = getLogger(OdtnManualTestCommand.class);

    public static enum Mode {
        ENABLE_TRANSCEIVER,
        DISABLE_TRANSCEIVER,
        PRECONF_TRANSCEIVER,
        PRECONF_OPTICAL_CHANNEL,
    }

    ModeCompleter modeCompleter;
    @Argument(index = 0, name = "mode", description = "one of Mode see source",
              required = true)
    String modeStr = Mode.ENABLE_TRANSCEIVER.name();
    Mode mode;

    // injecting dependency for OSGi package import generation purpose
    DeviceIdCompleter uriCompleter;
    @Option(name = "--deviceId", description = "Device ID URI to send configuration to",
              required = false)
    String uri = null;

    // TODO add completer for this?
    @Option(name = "--component",
            description = "Component name",
            required = false, multiValued = false)
    private String componentName = "TRANSCEIVER_1_1_4_1";


    // OSGi Services to be filled in at the beginning.
    private DynamicConfigService dcs;
    private DeviceService deviceService;


    void printlog(String format, Object... objs) {
        print(format.replaceAll(Pattern.quote("{}"), "%s"), objs);
        log.info(format, objs);
    }

    List<CharSequence> transform(List<DataNode> input) {
        ResourceId empty = ResourceId.builder().build();
        return Lists.transform(input,
                   node -> toCharSequence(toXmlCompositeStream(toCompositeData(toResourceData(empty, node)))));
    }


    @Override
    protected void execute() {
        dcs = get(DynamicConfigService.class);
        deviceService = get(DeviceService.class);

        try {
            mode = Mode.valueOf(modeStr);
        } catch (IllegalArgumentException e) {
            printlog("{} is not a valid Mode, pick one of {}",
                     modeStr,
                     Arrays.asList(Mode.values()),
                     e);
            return;
        }

        // effectively configuration context
        List<CharSequence> nodes = new ArrayList<>();

        // driver selection with fallback to plain OpenConfig
        DeviceId did = Optional.ofNullable(uri)
                        .map(DeviceId::deviceId)
                        .orElse(null);
        ConfigurableTransceiver transceiver =
            Optional.ofNullable(did)
            .map(deviceService::getDevice)
            .filter(device -> device.is(ConfigurableTransceiver.class))
            .map(device -> device.as(ConfigurableTransceiver.class))
            .orElseGet(() -> new PlainTransceiver());

        switch (mode) {
        case PRECONF_TRANSCEIVER:
            // note: these doesn't support driver
            nodes.addAll(transform(Transceiver.preconf(componentName)));
            break;

        case ENABLE_TRANSCEIVER:
            nodes.addAll(transceiver.enable(componentName, true));
            break;

        case DISABLE_TRANSCEIVER:
            nodes.addAll(transceiver.enable(componentName, false));
            break;

        case PRECONF_OPTICAL_CHANNEL:
            // note: these doesn't support driver
            nodes.addAll(transform(OpticalChannel.preconf(componentName)));
            break;

        default:
            printlog("Mode {} not supported yet", mode);
            break;
        }

        // Do something about it.
        doTheMagic(nodes);
    }

    void doTheMagic(List<CharSequence> nodes) {

        Document doc;
        try {
            doc = DocumentBuilderFactory.newInstance()
                    .newDocumentBuilder().newDocument();
        } catch (ParserConfigurationException e) {
            printlog("Unexpected error", e);
            throw new IllegalStateException(e);
        }

        // netconf rpc boilerplate part without message-id
        Element rpc = doc.createElementNS("urn:ietf:params:xml:ns:netconf:base:1.0", "rpc");
        doc.appendChild(rpc);
        Element editConfig = doc.createElement("edit-config");
        rpc.appendChild(editConfig);
        Element target = doc.createElement("target");
        editConfig.appendChild(target);
        target.appendChild(doc.createElement("running"));

        Element config = doc.createElement("config");
        config.setAttributeNS("http://www.w3.org/2000/xmlns/",
                            "xmlns:xc",
                            "urn:ietf:params:xml:ns:netconf:base:1.0");
        editConfig.appendChild(config);


        for (CharSequence node : nodes) {
            Document ldoc = toDocument(CharSource.wrap(node));
            Element cfgRoot = ldoc.getDocumentElement();

            // is everything as merge, ok?
            cfgRoot.setAttribute("xc:operation", "merge");

            // move (or copy) node to another Document
            config.appendChild(Optional.ofNullable(doc.adoptNode(cfgRoot))
                                  .orElseGet(() -> doc.importNode(cfgRoot, true)));

            // don't have good use for JSON for now
            //JsonNode json = toJsonNode(toJsonCompositeStream(toCompositeData(toResourceData(resourceId, node))));
            //printlog("JSON:\n{}", toCharSequence(json));
        }

        printlog("XML:\n{}", XmlString.prettifyXml(toCharSequence(doc)));

        // TODO if deviceId is given send it out to the device
        if (uri != null) {
            DeviceId deviceId = DeviceId.deviceId(uri);
            NetconfController ctr = get(NetconfController.class);
            Optional.ofNullable(ctr.getNetconfDevice(deviceId))
                .map(NetconfDevice::getSession)
                .ifPresent(session -> {
                    try {
                        session.rpc(toCharSequence(doc, false).toString()).join();
                    } catch (NetconfException e) {
                        log.error("Exception thrown", e);
                    }
                });
        }
    }
}
