/*
 * 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.net.driver;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.configuration.XMLConfiguration;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Utility capable of reading driver configuration XML resources and producing
 * a device driver provider as a result.
 * <p>
 * The drivers stream structure is as follows:
 * </p>
 * <pre>
 *     &lt;drivers&gt;
 *         &lt;driver name=“...” [manufacturer="..." hwVersion="..." swVersion="..."]&gt;
 *             &lt;behaviour api="..." impl="..."/&gt;
 *             ...
 *             [&lt;property name=“key”&gt;value&lt;/key&gt;]
 *             ...
 *         &lt;/driver&gt;
 *         ...
 *     &lt;/drivers&gt;
 * </pre>
 */
public class XmlDriverLoader {

    private static final String DRIVERS = "drivers";
    private static final String DRIVER = "driver";

    private static final String BEHAVIOUR = "behaviour";
    private static final String PROPERTY = "property";

    private static final String NAME = "[@name]";
    private static final String EXTENDS = "[@extends]";
    private static final String MFG = "[@manufacturer]";
    private static final String HW = "[@hwVersion]";
    private static final String SW = "[@swVersion]";
    private static final String API = "[@api]";
    private static final String IMPL = "[@impl]";

    private final ClassLoader classLoader;

    private Map<String, Driver> drivers = Maps.newHashMap();

    /**
     * Creates a new driver loader capable of loading drivers from the supplied
     * class loader.
     *
     * @param classLoader class loader to use
     */
    public XmlDriverLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
    }

    /**
     * Loads the specified drivers resource as an XML stream and parses it to
     * produce a ready-to-register driver provider.
     *
     * @param driversStream stream containing the drivers definitions
     * @param resolver      driver resolver
     * @return driver provider
     * @throws java.io.IOException if issues are encountered reading the stream
     *                             or parsing the driver definitions within
     */
    public DefaultDriverProvider loadDrivers(InputStream driversStream,
                                             DriverResolver resolver) throws IOException {
        try {
            XMLConfiguration cfg = new XMLConfiguration();
            cfg.setRootElementName(DRIVERS);
            cfg.setAttributeSplittingDisabled(true);

            cfg.load(driversStream);
            return loadDrivers(cfg, resolver);
        } catch (ConfigurationException e) {
            throw new IOException("Unable to load drivers", e);
        }
    }

    /**
     * Loads a driver provider from the supplied hierarchical configuration.
     *
     * @param driversCfg hierarchical configuration containing the drivers definitions
     * @param resolver   driver resolver
     * @return driver provider
     */
    public DefaultDriverProvider loadDrivers(HierarchicalConfiguration driversCfg,
                                             DriverResolver resolver) {
        DefaultDriverProvider provider = new DefaultDriverProvider();
        for (HierarchicalConfiguration cfg : driversCfg.configurationsAt(DRIVER)) {
            DefaultDriver driver = loadDriver(cfg, resolver);
            drivers.put(driver.name(), driver);
            provider.addDriver(driver);
        }
        drivers.clear();
        return provider;
    }

    /**
     * Loads a driver from the supplied hierarchical configuration.
     *
     * @param driverCfg hierarchical configuration containing the driver definition
     * @param resolver  driver resolver
     * @return driver
     */
    public DefaultDriver loadDriver(HierarchicalConfiguration driverCfg,
                                    DriverResolver resolver) {
        String name = driverCfg.getString(NAME);
        String parentsString = driverCfg.getString(EXTENDS, "");
        List<Driver> parents = Lists.newArrayList();
        if (!parentsString.equals("")) {
            List<String> parentsNames;
            if (parentsString.contains(",")) {
                parentsNames = Arrays.asList(parentsString.replace(" ", "").split(","));
            } else {
                parentsNames = Lists.newArrayList(parentsString);
            }
            parents = parentsNames.stream().map(parent -> (parent != null) ?
                    resolve(parent, resolver) : null).collect(Collectors.toList());
        }
        String manufacturer = driverCfg.getString(MFG, "");
        String hwVersion = driverCfg.getString(HW, "");
        String swVersion = driverCfg.getString(SW, "");
        return new DefaultDriver(name, parents, manufacturer, hwVersion, swVersion,
                                 parseBehaviours(driverCfg),
                                 parseProperties(driverCfg));
    }

    // Resolves the driver by name locally at first and then using the specified resolver.
    private Driver resolve(String parentName, DriverResolver resolver) {
        Driver driver = drivers.get(parentName);
        return driver != null ? driver :
                (resolver != null ? resolver.getDriver(parentName) : null);
    }

    // Parses the behaviours section.
    private Map<Class<? extends Behaviour>, Class<? extends Behaviour>>
    parseBehaviours(HierarchicalConfiguration driverCfg) {
        ImmutableMap.Builder<Class<? extends Behaviour>,
                Class<? extends Behaviour>> behaviours = ImmutableMap.builder();
        for (HierarchicalConfiguration b : driverCfg.configurationsAt(BEHAVIOUR)) {
            behaviours.put(getClass(b.getString(API)), getClass(b.getString(IMPL)));
        }
        return behaviours.build();
    }

    // Parses the properties section.
    private Map<String, String> parseProperties(HierarchicalConfiguration driverCfg) {
        ImmutableMap.Builder<String, String> properties = ImmutableMap.builder();
        for (HierarchicalConfiguration b : driverCfg.configurationsAt(PROPERTY)) {
            properties.put(b.getString(NAME), (String) b.getRootNode().getValue());
        }
        return properties.build();
    }

    @SuppressWarnings("unchecked")
    private Class<? extends Behaviour> getClass(String className) {
        try {
            return (Class<? extends Behaviour>) classLoader.loadClass(className);
        } catch (ClassNotFoundException e) {
            throw new IllegalArgumentException("Unable to load class " + className, e);
        }
    }

}
