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

import java.lang.reflect.Constructor;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.plugin.extensions.communication.MessageFactory;
import org.jetbrains.annotations.Nullable;

/**
 * Component type.
 */
public enum IgniteComponentType {
    /** IGFS. */
    IGFS(
        "org.apache.ignite.internal.processors.igfs.IgfsNoopProcessor",
        "org.apache.ignite.internal.processors.igfs.IgfsProcessor",
        "ignite-hadoop"
    ),

    /** Hadoop. */
    HADOOP(
        "org.apache.ignite.internal.processors.hadoop.HadoopNoopProcessor",
        "org.apache.ignite.internal.processors.hadoop.HadoopProcessor",
        "ignite-hadoop"
    ),

    /** Hadoop Helper component. */
    HADOOP_HELPER(
        "org.apache.ignite.internal.processors.hadoop.HadoopNoopHelper",
        "org.apache.ignite.internal.processors.hadoop.HadoopHelperImpl",
        "ignite-hadoop"
    ),

    /** IGFS helper component. */
    IGFS_HELPER(
        "org.apache.ignite.internal.processors.igfs.IgfsNoopHelper",
        "org.apache.ignite.internal.processors.igfs.IgfsHelperImpl",
        "ignite-hadoop"
    ),

    /** Spring XML parsing. */
    SPRING(
        null,
        "org.apache.ignite.internal.util.spring.IgniteSpringHelperImpl",
        "ignite-spring"
    ),

    /** Indexing. */
    INDEXING(
        null,
        "org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing",
        "ignite-indexing",
        "org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2ValueMessageFactory"
    ),

    /** Nodes starting using SSH. */
    SSH(
        null,
        "org.apache.ignite.internal.util.nodestart.IgniteSshHelperImpl",
        "ignite-ssh"
    ),

    /** Integration of cache transactions with JTA. */
    JTA(
        "org.apache.ignite.internal.processors.cache.jta.CacheNoopJtaManager",
        "org.apache.ignite.internal.processors.cache.jta.CacheJtaManager",
        "ignite-jta"
    ),

    /** Cron-based scheduling, see {@link org.apache.ignite.IgniteScheduler}. */
    SCHEDULE(
        "org.apache.ignite.internal.processors.schedule.IgniteNoopScheduleProcessor",
        "org.apache.ignite.internal.processors.schedule.IgniteScheduleProcessor",
        "ignite-schedule"
    );

    /** No-op class name. */
    private final String noOpClsName;

    /** Class name. */
    private final String clsName;

    /** Module name. */
    private final String module;

    /** Optional message factory for component. */
    private final String msgFactoryCls;

    /**
     * Constructor.
     *
     * @param noOpClsName Class name for no-op implementation.
     * @param clsName Class name.
     * @param module Module name.
     */
    IgniteComponentType(String noOpClsName, String clsName, String module) {
        this(noOpClsName, clsName, module, null);
    }

    /**
     * Constructor.
     *
     * @param noOpClsName Class name for no-op implementation.
     * @param clsName Class name.
     * @param module Module name.
     * @param msgFactoryCls {@link MessageFactory} class for the component.
     */
    IgniteComponentType(String noOpClsName, String clsName, String module, String msgFactoryCls) {
        this.noOpClsName = noOpClsName;
        this.clsName = clsName;
        this.module = module;
        this.msgFactoryCls = msgFactoryCls;
    }

    /**
     * @return Component class name.
     */
    public String className() {
        return clsName;
    }

    /**
     * @return Component module name.
     */
    public String module() {
        return module;
    }

    /**
     * Check whether real component class is in classpath.
     *
     * @return {@code True} if in classpath.
     */
    public boolean inClassPath() {
        try {
            Class.forName(clsName);

            return true;
        }
        catch (ClassNotFoundException ignore) {
            return false;
        }
    }

    /**
     * Creates component.
     *
     * @param ctx Kernal context.
     * @param noOp No-op flag.
     * @return Created component.
     * @throws IgniteCheckedException If failed.
     */
    public <T> T create(GridKernalContext ctx, boolean noOp) throws IgniteCheckedException {
        return create0(ctx, noOp ? noOpClsName : clsName);
    }

    /**
     * Creates component.
     *
     * @param ctx Kernal context.
     * @param mandatory If the component is mandatory.
     * @return Created component.
     * @throws IgniteCheckedException If failed.
     */
    public <T> T createIfInClassPath(GridKernalContext ctx, boolean mandatory)
        throws IgniteCheckedException {
        String cls = clsName;

        try {
            Class.forName(cls);
        }
        catch (ClassNotFoundException e) {
            if (mandatory)
                throw componentException(e);

            cls = noOpClsName;
        }

        return create0(ctx, cls);
    }

    /**
     * Creates component.
     *
     * @param noOp No-op flag.
     * @return Created component.
     * @throws IgniteCheckedException If failed.
     */
    public <T> T create(boolean noOp) throws IgniteCheckedException {
        return create0(null, noOp ? noOpClsName : clsName);
    }

    /**
     * First tries to find main component class, if it is not found creates no-op implementation.
     *
     * @param ctx Kernal context.
     * @return Created component or no-op implementation.
     * @throws IgniteCheckedException If failed.
     */
    public <T> T createOptional(GridKernalContext ctx) throws IgniteCheckedException {
        return createOptional0(ctx);
    }

    /**
     * First tries to find main component class, if it is not found creates no-op implementation.
     *
     * @return Created component or no-op implementation.
     * @throws IgniteCheckedException If failed.
     */
    public <T> T createOptional() throws IgniteCheckedException {
        return createOptional0(null);
    }

    /**
     * First tries to find main component class, if it is not found creates no-op implementation.
     *
     * @param ctx Kernal context.
     * @return Created component or no-op implementation.
     * @throws IgniteCheckedException If failed.
     */
    @SuppressWarnings("unchecked")
    private <T> T createOptional0(@Nullable GridKernalContext ctx) throws IgniteCheckedException {
        Class<?> cls;

        try {
            cls = Class.forName(clsName);
        }
        catch (ClassNotFoundException ignored) {
            try {
                cls = Class.forName(noOpClsName);
            }
            catch (ClassNotFoundException e) {
                throw new IgniteCheckedException("Failed to find both real component class and no-op class.", e);
            }
        }

        try {
            if (ctx == null) {
                Constructor<?> ctor = cls.getConstructor();

                return (T)ctor.newInstance();
            }
            else {
                Constructor<?> ctor = cls.getConstructor(GridKernalContext.class);

                return (T)ctor.newInstance(ctx);
            }
        }
        catch (Exception e) {
            throw componentException(e);
        }
    }

    /**
     * Creates component instance.
     *
     * @param ctx Kernal context.
     * @param clsName Component class name.
     * @return Component instance.
     * @throws IgniteCheckedException If failed.
     */
    @SuppressWarnings("unchecked")
    private <T> T create0(@Nullable GridKernalContext ctx, String clsName) throws IgniteCheckedException {
        try {
            Class<?> cls = Class.forName(clsName);

            if (ctx == null) {
                Constructor<?> ctor = cls.getConstructor();

                return (T)ctor.newInstance();
            }
            else {
                Constructor<?> ctor = cls.getConstructor(GridKernalContext.class);

                return (T)ctor.newInstance(ctx);
            }
        }
        catch (Throwable e) {
            throw componentException(e);
        }
    }

    /**
     * Creates message factory for the component.
     *
     * @return Message factory or {@code null} if none or the component is not in classpath.
     * @throws IgniteCheckedException If failed.
     */
    @Nullable public MessageFactory messageFactory() throws IgniteCheckedException {
        Class<?> cls;

        if (msgFactoryCls == null || null == (cls = U.classForName(msgFactoryCls, null)))
            return null;

        return (MessageFactory)U.newInstance(cls);
    }

    /**
     * @param err Creation error.
     * @return Component creation exception.
     */
    private IgniteCheckedException componentException(Throwable err) {
        return new IgniteCheckedException("Failed to create Ignite component (consider adding " + module +
            " module to classpath) [component=" + this + ", cls=" + clsName + ']', err);
    }
}