/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you 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.apache.tinkerpop.gremlin.structure.io.util;

import org.apache.commons.configuration2.Configuration;
import org.apache.tinkerpop.gremlin.structure.io.IoRegistry;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @author Marko A. Rodriguez (http://markorodriguez.com)
 */
public final class IoRegistryHelper {

    private IoRegistryHelper() {

    }

    public static List<IoRegistry> createRegistries(final List<Object> registryNamesClassesOrInstances) {
        if (registryNamesClassesOrInstances.isEmpty()) return Collections.emptyList();

        final List<IoRegistry> registries = new ArrayList<>();
        for (final Object object : registryNamesClassesOrInstances) {
            if (object instanceof IoRegistry)
                registries.add((IoRegistry) object);
            else if (object instanceof String || object instanceof Class) {
                try {
                    final Class<?> clazz = object instanceof String ? Class.forName((String) object) : (Class) object;
                    Method instanceMethod = null;
                    try {
                        instanceMethod = clazz.getDeclaredMethod("instance"); // try for getInstance() ??
                    } catch (final NoSuchMethodException e) {
                        try {
                            // even though use of "getInstance" is no longer a thing in tinkerpop as of 3.3.0, perhaps
                            // others are using this style of naming. Doesn't seem to harm anything to continue to
                            // check for that method.
                            instanceMethod = clazz.getDeclaredMethod("getInstance"); // try for getInstance() ??
                        } catch (final NoSuchMethodException e2) {
                            // no instance() or getInstance() methods
                        }
                    }
                    if (null != instanceMethod && IoRegistry.class.isAssignableFrom(instanceMethod.getReturnType()))
                        registries.add((IoRegistry) instanceMethod.invoke(null));
                    else
                        registries.add((IoRegistry) clazz.newInstance()); // no instance() or getInstance() methods, try instantiate class
                } catch (final Exception e) {
                    throw new IllegalStateException(e.getMessage(), e);
                }
            } else {
                throw new IllegalArgumentException("The provided registry object can not be resolved to an instance: " + object);
            }
        }
        return registries;
    }

    public static List<IoRegistry> createRegistries(final Configuration configuration) {
        if (configuration.containsKey(IoRegistry.IO_REGISTRY)) {
            final Object property = configuration.getProperty(IoRegistry.IO_REGISTRY);
            if (property instanceof IoRegistry)
                return Collections.singletonList((IoRegistry) property);
            else if (property instanceof List)
                return createRegistries((List) property);
            else if (property instanceof String)
                return createRegistries(Arrays.asList(((String) property).split(",")));
            else
                throw new IllegalArgumentException("The provided registry object can not be resolved to an instance: " + property);
        } else
            return Collections.emptyList();
    }
}
