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

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import org.apache.freemarker.core.model.TemplateBooleanModel;
import org.apache.freemarker.core.model.TemplateHashModelEx;
import org.apache.freemarker.core.model.TemplateIterableModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelIterator;
import org.apache.freemarker.core.model.TemplateNodeModel;
import org.apache.freemarker.core.model.TemplateNullModel;
import org.apache.freemarker.core.model.impl.SimpleNumber;
import org.apache.freemarker.core.util._StringUtils;

/**
 * AST directive node: {@code #list} element, or pre-{@code #else} section of it inside a
 * {@link ASTDirListElseContainer}.
 */
final class ASTDirList extends ASTDirective {

    private final ASTExpression listedExp;
    private final String nestedContentParam1Name;
    private final String nestedContentParam2Name;
    private final boolean hashListing;

    /**
     * @param listedExp
     *            a variable referring to an iterable or extended hash that we want to list
     * @param nestedContentParam1Name
     *            The name of the variable that will hold the value of the current item when looping through listed value,
     *            or {@code null} if we have a nested {@code #items}. If this is a hash listing then this variable will holds the value
     *            of the hash key.
     * @param nestedContentParam2Name
     *            The name of the variable that will hold the value of the current item when looping through the list,
     *            or {@code null} if we have a nested {@code #items}. If this is a hash listing then it variable will hold the value
     *            from the key-value pair.
     * @param childrenBeforeElse
     *            The nested content to execute if the listed value wasn't empty; can't be {@code null}. If the
     *            nested content parameter is specified in the start tag, this is also what we will iterate over.
     * @param hashListing
     *            Whether this is a key-value pair listing, or a usual listing. This is properly set even if we have
     *            a nested {@code #items}.
     */
    ASTDirList(ASTExpression listedExp,
                  String nestedContentParam1Name,
                  String nestedContentParam2Name,
                  TemplateElements childrenBeforeElse,
                  boolean hashListing) {
        this.listedExp = listedExp;
        this.nestedContentParam1Name = nestedContentParam1Name;
        this.nestedContentParam2Name = nestedContentParam2Name;
        setChildren(childrenBeforeElse);
        this.hashListing = hashListing;
    }
    
    boolean isHashListing() {
        return hashListing;
    }

    @Override
    ASTElement[] execute(Environment env) throws TemplateException, IOException {
        acceptWithResult(env);
        return null;
    }
    
    boolean acceptWithResult(Environment env) throws TemplateException, IOException {
        TemplateModel listedValue = listedExp.eval(env);
        if (listedValue == null) {
            listedExp.assertNonNull(null, env);
        }

        return env.visitIteratorBlock(new IterationContext(listedValue, nestedContentParam1Name, nestedContentParam2Name));
    }

    @Override
    String dump(boolean canonical) {
        StringBuilder buf = new StringBuilder();
        if (canonical) buf.append('<');
        buf.append(getLabelWithoutParameters());
        buf.append(' ');
        buf.append(listedExp.getCanonicalForm());
        if (nestedContentParam1Name != null) {
            buf.append(" as ");
            buf.append(_StringUtils.toFTLTopLevelIdentifierReference(nestedContentParam1Name));
            if (nestedContentParam2Name != null) {
                buf.append(", ");
                buf.append(_StringUtils.toFTLTopLevelIdentifierReference(nestedContentParam2Name));
            }
        }
        if (canonical) {
            buf.append(">");
            buf.append(getChildrenCanonicalForm());
            if (!(getParent() instanceof ASTDirListElseContainer)) {
                buf.append("</");
                buf.append(getLabelWithoutParameters());
                buf.append('>');
            }
        }
        return buf.toString();
    }
    
    @Override
    int getParameterCount() {
        return 1 + (nestedContentParam1Name != null ? 1 : 0) + (nestedContentParam2Name != null ? 1 : 0);
    }

    @Override
    Object getParameterValue(int idx) {
        switch (idx) {
        case 0:
            return listedExp;
        case 1:
            if (nestedContentParam1Name == null) throw new IndexOutOfBoundsException();
            return nestedContentParam1Name;
        case 2:
            if (nestedContentParam2Name == null) throw new IndexOutOfBoundsException();
            return nestedContentParam2Name;
        default: throw new IndexOutOfBoundsException();
        }
    }

    @Override
    ParameterRole getParameterRole(int idx) {
        switch (idx) {
        case 0:
            return ParameterRole.LIST_SOURCE;
        case 1:
            if (nestedContentParam1Name == null) throw new IndexOutOfBoundsException();
            return ParameterRole.NESTED_CONTENT_PARAMETER;
        case 2:
            if (nestedContentParam2Name == null) throw new IndexOutOfBoundsException();
            return ParameterRole.NESTED_CONTENT_PARAMETER;
        default: throw new IndexOutOfBoundsException();
        }
    }    
    
    @Override
    public String getLabelWithoutParameters() {
        return "#list";
    }

    @Override
    boolean isNestedBlockRepeater() {
        return nestedContentParam1Name != null;
    }

    /**
     * Holds the context of a #list directive.
     */
    class IterationContext implements LocalContext {
        
        private static final String LOOP_STATE_HAS_NEXT = "_has_next"; // lenght: 9
        private static final String LOOP_STATE_INDEX = "_index"; // length 6
        
        private Object openedIterator;
        private boolean hasNext;
        private TemplateModel nestedContentParam;
        private TemplateModel nestedContentParam2;
        private int index;
        private boolean alreadyEntered;
        private Collection localVarNames = null;
        
        /** If the {@code #list} has nested {@code #items}, it's {@code null} outside the {@code #items}. */
        private String nestedContentParam1Name;
        /** Used if we list key-value pairs */
        private String nestedContentParam2Name;
        /**
         * Whether the nested content parameters are visible from the template at the moment.
         * It would be more intuitive if the {@link LocalContext} is not in the local stack when they aren't visible,
         * but the {@link LocalContext} is also used for {@code #items} to find its parent, for which we need the tricky
         * scoping of the local context stack {@link Environment#getLocalContextStack()}.
         */
        private boolean nestedContentParamsVisible;
        
        private final TemplateModel listedValue;
        
        public IterationContext(TemplateModel listedValue,
                String nestedContentParamName, String nestedContentParam2Name) {
            this.listedValue = listedValue;
            this.nestedContentParam1Name = nestedContentParamName;
            this.nestedContentParam2Name = nestedContentParam2Name;
        }
        
        boolean accept(Environment env) throws TemplateException, IOException {
            return executeNestedContent(env, getChildBuffer());
        }

        void loopForItemsElement(Environment env, ASTElement[] childBuffer,
                String nestedContentParamName, String nestedContentParam2Name)
                throws TemplateException, IOException {
            try {
                if (alreadyEntered) {
                    throw new TemplateException(env,
                            "The #items directive was already entered earlier for this listing.");
                }
                alreadyEntered = true;
                this.nestedContentParam1Name = nestedContentParamName;
                this.nestedContentParam2Name = nestedContentParam2Name;
                executeNestedContent(env, childBuffer);
            } finally {
                this.nestedContentParam1Name = null;
                this.nestedContentParam2Name = null;
            }
        }

        /**
         * Executes the given block for the {@link #listedValue}: if {@link #nestedContentParam1Name} is non-{@code
         * null}, then for each list item once, otherwise once if {@link #listedValue} isn't empty.
         */
        private boolean executeNestedContent(Environment env, ASTElement[] childBuffer)
                throws TemplateException, IOException {
            return !hashListing
                    ? executedNestedContentForIterableListing(env, childBuffer)
                    : executedNestedContentForHashListing(env, childBuffer);
        }

        private boolean executedNestedContentForIterableListing(Environment env, ASTElement[] childBuffer)
                throws IOException, TemplateException {
            final boolean listNotEmpty;
            if (listedValue instanceof TemplateIterableModel) {
                final TemplateIterableModel collModel = (TemplateIterableModel) listedValue;
                final TemplateModelIterator iterModel
                        = openedIterator == null ? collModel.iterator()
                                : ((TemplateModelIterator) openedIterator);
                listNotEmpty = iterModel.hasNext();
                if (listNotEmpty) {
                    if (nestedContentParam1Name != null) {
                        listLoop: do {
                                nestedContentParam = iterModel.next();
                                hasNext = iterModel.hasNext();
                                try {
                                    nestedContentParamsVisible = true;
                                    env.executeElements(childBuffer);
                                } catch (BreakOrContinueException br) {
                                    if (br == BreakOrContinueException.BREAK_INSTANCE) {
                                        break listLoop;
                                    }
                                } finally {
                                    nestedContentParamsVisible = false;
                                }
                                index++;
                            } while (hasNext);
                        openedIterator = null;
                    } else {
                        // We must reuse this later, because some TemplateIterableModel can only allow one iterator()
                        // call (such as those wrapping an Iterator).
                        openedIterator = iterModel;
                        // Note: Nested content parameters will only become visible inside #items
                        env.executeElements(childBuffer);
                    }
                }
            } else if (listedValue instanceof TemplateHashModelEx) {
                throw new TemplateException(env,
                        new _ErrorDescriptionBuilder("The value you try to list is ",
                                new _DelayedAOrAn(new _DelayedTemplateLanguageTypeDescription(listedValue)),
                                ", thus you must declare two nested content parameters after the \"as\"; one for the "
                                + "key, and another for the value, like ", "<#... as k, v>", ")."
                                ));
            } else {
                throw MessageUtils.newUnexpectedOperandTypeException(
                        listedExp, listedValue,
                        MessageUtils.EXPECTED_TYPE_ITERABLE_DESC,
                        TemplateIterableModel.class,
                        null, env);
            }
            return listNotEmpty;
        }

        private boolean executedNestedContentForHashListing(Environment env, ASTElement[] childBuffer)
                throws IOException, TemplateException {
            final boolean hashNotEmpty;
            if (listedValue instanceof TemplateHashModelEx) {
                TemplateHashModelEx listedHash = (TemplateHashModelEx) listedValue; 
                TemplateHashModelEx.KeyValuePairIterator kvpIter
                        = openedIterator == null ? listedHash.keyValuePairIterator()
                                : (TemplateHashModelEx.KeyValuePairIterator) openedIterator;
                hashNotEmpty = kvpIter.hasNext();
                if (hashNotEmpty) {
                    if (nestedContentParam1Name != null) {
                        listLoop: do {
                            TemplateHashModelEx.KeyValuePair kvp = kvpIter.next();
                            nestedContentParam = kvp.getKey();
                            nestedContentParam2 = kvp.getValue();
                            hasNext = kvpIter.hasNext();
                            try {
                                nestedContentParamsVisible = true;
                                env.executeElements(childBuffer);
                            } catch (BreakOrContinueException br) {
                                if (br == BreakOrContinueException.BREAK_INSTANCE) {
                                    break listLoop;
                                }
                            } finally {
                                nestedContentParamsVisible = false;
                            }
                            index++;
                        } while (hasNext);
                        openedIterator = null;
                    } else {
                        // We will reuse this at the #iterms
                        openedIterator = kvpIter;
                        // Note: Nested content parameters will only become visible inside #items
                        env.executeElements(childBuffer);
                    }
                }
            } else if (listedValue instanceof TemplateIterableModel) {
                throw new TemplateException(env,
                        new _ErrorDescriptionBuilder("The value you try to list is ",
                                new _DelayedAOrAn(new _DelayedTemplateLanguageTypeDescription(listedValue)),
                                ", thus you must declare only one nested content parameter after the \"as\" (there's "
                                + "no separate key and value)."
                                ));
            } else {
                throw MessageUtils.newUnexpectedOperandTypeException(
                        listedExp, listedValue, TemplateHashModelEx.class, env);
            }
            return hashNotEmpty;
        }

        String getNestedContentParameter1Name() {
            return nestedContentParam1Name;
        }

        String getNestedContentParameter2Name() {
            return nestedContentParam2Name;
        }
        
        @Override
        public TemplateModel getLocalVariable(String name) {
            if (!nestedContentParamsVisible) {
                return null;
            }

            String nestedContentParamName = this.nestedContentParam1Name;
            if (name.startsWith(nestedContentParamName)) {
                switch(name.length() - nestedContentParamName.length()) {
                    case 0:
                        // TODO [FM3][null] Later nestedContentParam == null will mean undefined, which should be an error
                        return nestedContentParam != null ? nestedContentParam : TemplateNullModel.INSTANCE;
                    case 6: 
                        if (name.endsWith(LOOP_STATE_INDEX)) {
                            return new SimpleNumber(index);
                        }
                        break;
                    case 9: 
                        if (name.endsWith(LOOP_STATE_HAS_NEXT)) {
                            return hasNext ? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
                        }
                        break;
                }
            }
            
            if (name.equals(nestedContentParam2Name)) {
                return nestedContentParam2 != null ? nestedContentParam2 : TemplateNullModel.INSTANCE;
            }
            
            return null;
        }
        
        @Override
        public Collection<String> getLocalVariableNames() {
            if (!nestedContentParamsVisible) {
                return Collections.EMPTY_LIST;
            }

            String nestedContentParamName = this.nestedContentParam1Name;
            if (localVarNames == null) {
                localVarNames = new ArrayList(3);
                localVarNames.add(nestedContentParamName);
                localVarNames.add(nestedContentParamName + LOOP_STATE_INDEX);
                localVarNames.add(nestedContentParamName + LOOP_STATE_HAS_NEXT);
            }
            return localVarNames;
        }

        boolean hasNext() {
            return hasNext;
        }
        
        int getIndex() {
            return index;
        }
        
    }
    
}
