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

import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.commons.configuration2.builder.fluent.Configurations;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.hugegraph.config.CoreOptions;
import org.apache.hugegraph.config.HugeConfig;
import org.apache.hugegraph.event.EventHub;
import org.apache.hugegraph.task.TaskManager;
import org.apache.hugegraph.traversal.algorithm.OltpTraverser;
import org.apache.hugegraph.type.define.SerialEnum;
import org.apache.hugegraph.util.E;
import org.apache.hugegraph.util.Log;
import org.slf4j.Logger;

public class HugeFactory {

    private static final Logger LOG = Log.logger(HugeFactory.class);

    private static final Thread SHUT_DOWN_HOOK = new Thread(() -> {
        LOG.info("HugeGraph is shutting down");
        HugeFactory.shutdown(30L, true);
    }, "hugegraph-shutdown");

    static {
        SerialEnum.registerInternalEnums();
        HugeGraph.registerTraversalStrategies(StandardHugeGraph.class);

        Runtime.getRuntime().addShutdownHook(SHUT_DOWN_HOOK);
    }

    private static final String NAME_REGEX = "^[A-Za-z][A-Za-z0-9_]{0,47}$";

    private static final Map<String, HugeGraph> GRAPHS = new HashMap<>();

    private static final AtomicBoolean SHUT_DOWN = new AtomicBoolean(false);

    public static synchronized HugeGraph open(Configuration config) {
        HugeConfig conf = config instanceof HugeConfig ?
                          (HugeConfig) config : new HugeConfig(config);
        return open(conf);
    }

    public static synchronized HugeGraph open(HugeConfig config) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            // Not allowed to read file via Gremlin when SecurityManager enabled
            String configFileName;
            File configFile = config.file();
            if (configFile == null) {
                configFileName = config.toString();
            } else {
                configFileName = configFile.getName();
            }
            sm.checkRead(configFileName);
        }

        String name = config.get(CoreOptions.STORE);
        checkGraphName(name, "graph config(like hugegraph.properties)");
        name = name.toLowerCase();
        HugeGraph graph = GRAPHS.get(name);
        if (graph == null || graph.closed()) {
            graph = new StandardHugeGraph(config);
            GRAPHS.put(name, graph);
        } else {
            String backend = config.get(CoreOptions.BACKEND);
            E.checkState(backend.equalsIgnoreCase(graph.backend()),
                         "Graph name '%s' has been used by backend '%s'",
                         name, graph.backend());
        }
        return graph;
    }

    public static HugeGraph open(String path) {
        return open(getLocalConfig(path));
    }

    public static HugeGraph open(URL url) {
        return open(getRemoteConfig(url));
    }

    public static void remove(HugeGraph graph) {
        String name = graph.option(CoreOptions.STORE);
        GRAPHS.remove(name);
    }

    public static void checkGraphName(String name, String configFile) {
        E.checkArgument(name.matches(NAME_REGEX),
                        "Invalid graph name '%s' in %s, " +
                        "valid graph name is up to 48 alpha-numeric " +
                        "characters and underscores and only letters are " +
                        "supported as first letter. " +
                        "Note: letter is case insensitive", name, configFile);
    }

    public static PropertiesConfiguration getLocalConfig(String path) {
        File file = new File(path);
        E.checkArgument(file.exists() && file.isFile() && file.canRead(),
                        "Please specify a proper config file rather than: %s",
                        file.toString());
        try {
            return new Configurations().properties(file);
        } catch (ConfigurationException e) {
            throw new HugeException("Unable to load config file: %s", e, path);
        }
    }

    public static PropertiesConfiguration getRemoteConfig(URL url) {
        try {
            return new Configurations().properties(url);
        } catch (ConfigurationException e) {
            throw new HugeException("Unable to load remote config file: %s",
                                    e, url);
        }
    }

    public static void shutdown(long timeout) {
        shutdown(timeout, false);
    }

    /**
     * Stop all the daemon threads
     *
     * @param timeout         wait in seconds
     * @param ignoreException don't throw exception if true
     */
    public static void shutdown(long timeout, boolean ignoreException) {
        if (!SHUT_DOWN.compareAndSet(false, true)) {
            return;
        }
        try {
            if (!EventHub.destroy(timeout)) {
                throw new TimeoutException(timeout + "s");
            }
            TaskManager.instance().shutdown(timeout);
            OltpTraverser.destroy();
        } catch (Throwable e) {
            LOG.error("Error while shutdown", e);
            SHUT_DOWN.compareAndSet(true, false);
            if (ignoreException) {
                return;
            } else {
                throw new HugeException("Failed to shutdown", e);
            }
        }

        LOG.info("HugeFactory shutdown");
    }

    public static void removeShutdownHook() {
        Runtime.getRuntime().removeShutdownHook(SHUT_DOWN_HOOK);
    }
}
