/*
 * 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 freemarker.ext.jsp;

import java.io.IOException;
import java.io.Writer;
import java.util.List;
import java.util.Map;

import freemarker.core.BugException;
import freemarker.core.Environment;
import freemarker.core._UnexpectedTypeErrorExplainerTemplateModel;
import freemarker.ext.beans.SimpleMethodModel;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateSequenceModel;
import freemarker.template.TemplateTransformModel;
import freemarker.template.utility.ClassUtil;

/**
 * Used when a custom JSP tag and an EL function uses the same name in a tag library, to create a single FTL value from
 * the two. As FTL as no separate namespace for "tags" and functions, both aspect has to be implemented by the same
 * value.
 * 
 * @since 2.3.25
 */
@SuppressWarnings("rawtypes")
class CustomTagAndELFunctionCombiner {

    /**
     * @param customTag
     *            Either a {@link TemplateDirectiveModel} or a {@link TemplateTransformModel}.
     */
    static TemplateModel combine(TemplateModel customTag, TemplateMethodModelEx elFunction) {
        if (customTag instanceof TemplateDirectiveModel) {
            return elFunction instanceof SimpleMethodModel //
                    ? new TemplateDirectiveModelAndSimpleMethodModel( //
                            (TemplateDirectiveModel) customTag, (SimpleMethodModel) elFunction) //
                    : new TemplateDirectiveModelAndTemplateMethodModelEx( //
                            (TemplateDirectiveModel) customTag, elFunction);
        } else if (customTag instanceof TemplateTransformModel) {
            return (elFunction instanceof SimpleMethodModel)
                    ? new TemplateTransformModelAndSimpleMethodModel( //
                            (TemplateTransformModel) customTag, (SimpleMethodModel) elFunction) //
                    : new TemplateTransformModelAndTemplateMethodModelEx( //
                            (TemplateTransformModel) customTag, elFunction);
        } else {
            throw new BugException(
                    "Unexpected custom JSP tag class: " + ClassUtil.getShortClassNameOfObject(customTag));
        }
    }

    /**
     * Tells if the value can be used as the "custom tag" parameter to
     * {@link #combine(TemplateModel, TemplateMethodModelEx)}.
     */
    static boolean canBeCombinedAsCustomTag(TemplateModel tm) {
        return (tm instanceof TemplateDirectiveModel || tm instanceof TemplateTransformModel)
                && !(tm instanceof CombinedTemplateModel);
    }

    /**
     * Tells if the value can be used as the "EL function" parameter to
     * {@link #combine(TemplateModel, TemplateMethodModelEx)}.
     */
    static boolean canBeCombinedAsELFunction(TemplateModel tm) {
        return tm instanceof TemplateMethodModelEx && !(tm instanceof CombinedTemplateModel);
    }

    private static class CombinedTemplateModel {
        // Marker only
    };

    private static class TemplateDirectiveModelAndSimpleMethodModel extends CombinedTemplateModel
            implements TemplateDirectiveModel, TemplateMethodModelEx, TemplateSequenceModel,
            _UnexpectedTypeErrorExplainerTemplateModel {

        private final TemplateDirectiveModel templateDirectiveModel;
        private final SimpleMethodModel simpleMethodModel;

        public TemplateDirectiveModelAndSimpleMethodModel( //
                TemplateDirectiveModel templateDirectiveModel, SimpleMethodModel simpleMethodModel) {
            this.templateDirectiveModel = templateDirectiveModel;
            this.simpleMethodModel = simpleMethodModel;
        }

        @Override
        public Object exec(List arguments) throws TemplateModelException {
            return simpleMethodModel.exec(arguments);
        }

        @Override
        public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
                throws TemplateException, IOException {
            templateDirectiveModel.execute(env, params, loopVars, body);
        }

        @Override
        public Object[] explainTypeError(Class[] expectedClasses) {
            return simpleMethodModel.explainTypeError(expectedClasses);
        }

        @Override
        public TemplateModel get(int index) throws TemplateModelException {
            return simpleMethodModel.get(index);
        }

        @Override
        public int size() throws TemplateModelException {
            return simpleMethodModel.size();
        }

    }

    private static class TemplateDirectiveModelAndTemplateMethodModelEx extends CombinedTemplateModel
            implements TemplateDirectiveModel, TemplateMethodModelEx {

        private final TemplateDirectiveModel templateDirectiveModel;
        private final TemplateMethodModelEx templateMethodModelEx;

        public TemplateDirectiveModelAndTemplateMethodModelEx( //
                TemplateDirectiveModel templateDirectiveModel, TemplateMethodModelEx templateMethodModelEx) {
            this.templateDirectiveModel = templateDirectiveModel;
            this.templateMethodModelEx = templateMethodModelEx;
        }

        @Override
        public Object exec(List arguments) throws TemplateModelException {
            return templateMethodModelEx.exec(arguments);
        }

        @Override
        public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
                throws TemplateException, IOException {
            templateDirectiveModel.execute(env, params, loopVars, body);
        }

    }

    private static class TemplateTransformModelAndTemplateMethodModelEx extends CombinedTemplateModel
            implements TemplateTransformModel, TemplateMethodModelEx {

        private final TemplateTransformModel templateTransformModel;
        private final TemplateMethodModelEx templateMethodModelEx;

        public TemplateTransformModelAndTemplateMethodModelEx( //
                TemplateTransformModel templateTransformModel, TemplateMethodModelEx templateMethodModelEx) {
            this.templateTransformModel = templateTransformModel;
            this.templateMethodModelEx = templateMethodModelEx;
        }

        @Override
        public Object exec(List arguments) throws TemplateModelException {
            return templateMethodModelEx.exec(arguments);
        }

        @Override
        public Writer getWriter(Writer out, Map args) throws TemplateModelException, IOException {
            return templateTransformModel.getWriter(out, args);
        }

    }

    private static class TemplateTransformModelAndSimpleMethodModel extends CombinedTemplateModel
            implements TemplateTransformModel, TemplateMethodModelEx, TemplateSequenceModel,
            _UnexpectedTypeErrorExplainerTemplateModel {

        private final TemplateTransformModel templateTransformModel;
        private final SimpleMethodModel simpleMethodModel;

        public TemplateTransformModelAndSimpleMethodModel( //
                TemplateTransformModel templateTransformModel, SimpleMethodModel simpleMethodModel) {
            this.templateTransformModel = templateTransformModel;
            this.simpleMethodModel = simpleMethodModel;
        }

        @Override
        public Object exec(List arguments) throws TemplateModelException {
            return simpleMethodModel.exec(arguments);
        }

        @Override
        public Object[] explainTypeError(Class[] expectedClasses) {
            return simpleMethodModel.explainTypeError(expectedClasses);
        }

        @Override
        public TemplateModel get(int index) throws TemplateModelException {
            return simpleMethodModel.get(index);
        }

        @Override
        public int size() throws TemplateModelException {
            return simpleMethodModel.size();
        }

        @Override
        public Writer getWriter(Writer out, Map args) throws TemplateModelException, IOException {
            return templateTransformModel.getWriter(out, args);
        }

    }

}
