/**
 * Copyright (C) 2006 Google Inc.
 * <p>
 * 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
 * </p>
 *  http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * 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.
 * </p>
 */

package com.opensymphony.xwork2.inject;

import java.util.concurrent.Callable;

/**
 * Scope of an injected objects.
 *
 * @author crazybob
 */
public enum Scope {

    /**
     * One instance per injection.
     */
    PROTOTYPE {
        @Override
        <T> InternalFactory<? extends T> scopeFactory(Class<T> type, String name,
                                                      InternalFactory<? extends T> factory) {
            return InitializableFactory.wrapIfNeeded(factory);
        }
    },

    /**
     * One instance per container.
     */
    SINGLETON {
        @Override
        <T> InternalFactory<? extends T> scopeFactory(Class<T> type, String name, final InternalFactory<? extends T> factory) {
            return new InternalFactory<T>() {
                volatile T instance;

                public T create(InternalContext context) {
                    if (instance == null) {
                        synchronized (context.getContainer()) {
                            if (instance == null) {
                                instance = InitializableFactory.wrapIfNeeded(factory).create(context);
                            }
                        }
                    }
                    return instance;
                }

                @Override
                public Class<? extends T> type() {
                    return factory.type();
                }

                @Override
                public String toString() {
                    return factory.toString();
                }
            };
        }
    },

    /**
     * <p>
     * One instance per thread.
     * </p>
     *
     * <p>
     * <b>Note:</b> if a thread local object strongly references its {@link
     * Container}, neither the {@code Container} nor the object will be
     * eligible for garbage collection, i.e. memory leak.
     * </p>
     */
    THREAD {
        @Override
        <T> InternalFactory<? extends T> scopeFactory(Class<T> type, String name, final InternalFactory<? extends T> factory) {
            return new InternalFactory<T>() {
                final ThreadLocal<T> threadLocal = new ThreadLocal<>();

                public T create(final InternalContext context) {
                    T t = threadLocal.get();
                    if (t == null) {
                        t = InitializableFactory.wrapIfNeeded(factory).create(context);
                        threadLocal.set(t);
                    }
                    return t;
                }

                @Override
                public Class<? extends T> type() {
                    return factory.type();
                }

                @Override
                public String toString() {
                    return factory.toString();
                }
            };
        }
    },

    /**
     * One instance per request.
     */
    REQUEST {
        @Override
        <T> InternalFactory<? extends T> scopeFactory(final Class<T> type, final String name, final InternalFactory<? extends T> factory) {
            return new InternalFactory<T>() {
                public T create(InternalContext context) {
                    Strategy strategy = context.getScopeStrategy();
                    try {
                        return strategy.findInRequest(
                                type, name, toCallable(context, factory));
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }

                @Override
                public Class<? extends T> type() {
                    return factory.type();
                }

                @Override
                public String toString() {
                    return factory.toString();
                }
            };
        }
    },

    /**
     * One instance per session.
     */
    SESSION {
        @Override
        <T> InternalFactory<? extends T> scopeFactory(final Class<T> type, final String name, final InternalFactory<? extends T> factory) {
            return new InternalFactory<T>() {
                public T create(InternalContext context) {
                    Strategy strategy = context.getScopeStrategy();
                    try {
                        return strategy.findInSession(
                                type, name, toCallable(context, factory));
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }

                @Override
                public Class<? extends T> type() {
                    return factory.type();
                }

                @Override
                public String toString() {
                    return factory.toString();
                }
            };
        }
    },

    /**
     * One instance per wizard.
     */
    WIZARD {
        @Override
        <T> InternalFactory<? extends T> scopeFactory(final Class<T> type, final String name, final InternalFactory<? extends T> factory) {
            return new InternalFactory<T>() {
                public T create(InternalContext context) {
                    Strategy strategy = context.getScopeStrategy();
                    try {
                        return strategy.findInWizard(
                                type, name, toCallable(context, factory));
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }

                @Override
                public Class<? extends T> type() {
                    return factory.type();
                }

                @Override
                public String toString() {
                    return factory.toString();
                }
            };
        }
    };

    <T> Callable<? extends T> toCallable(final InternalContext context,
                                         final InternalFactory<? extends T> factory) {
        return new Callable<T>() {
            public T call() throws Exception {
                return InitializableFactory.wrapIfNeeded(factory).create(context);
            }
        };
    }

    /**
     * Wraps factory with scoping logic.
     *
     * @param type type of object
     * @param name name of object
     * @param factory factory
     *
     * @return the factory for the given type and name
     */
    abstract <T> InternalFactory<? extends T> scopeFactory(
            Class<T> type, String name, InternalFactory<? extends T> factory);

    /**
     * Pluggable scoping strategy. Enables users to provide custom
     * implementations of request, session, and wizard scopes. Implement and
     * pass to {@link
     * Container#setScopeStrategy(com.opensymphony.xwork2.inject.Scope.Strategy)}.
     */
    public interface Strategy {

        /**
         * Finds an object for the given type and name in the request scope.
         * Creates a new object if necessary using the given factory.
         *
         * @param <T> generic type
         * @param type type of object
         * @param name name of object
         * @param factory factory
         *
         * @return the object for the given type and name in the request scope
         *
         * @throws Exception in case of any error
         */
        <T> T findInRequest(Class<T> type, String name,
                            Callable<? extends T> factory) throws Exception;

        /**
         * Finds an object for the given type and name in the session scope.
         * Creates a new object if necessary using the given factory.
         *
         * @param <T> generic type
         * @param type type of object
         * @param name name of object
         * @param factory factory
         *
         * @return the object for the given type and name in the session scope
         *
         * @throws Exception in case of any error
         */
        <T> T findInSession(Class<T> type, String name,
                            Callable<? extends T> factory) throws Exception;

        /**
         * Finds an object for the given type and name in the wizard scope.
         * Creates a new object if necessary using the given factory.
         *
         * @param <T> generic type
         * @param type type of object
         * @param name name of object
         * @param factory factory
         *
         * @return the object for the given type and name in the wizard scope
         *
         * @throws Exception in case of any error
         */
        <T> T findInWizard(Class<T> type, String name,
                           Callable<? extends T> factory) throws Exception;
    }
}
