/*
 *  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.codehaus.groovy.ast;

import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Represents a variable scope. This is primarily used to determine variable sharing
 * across method and closure boundaries.
 */
public class VariableScope  {

    private VariableScope parent;
    private ClassNode classScope;
    private boolean inStaticContext;
    private boolean resolvesDynamic;

    private Map<String, Variable> declaredVariables = Collections.emptyMap();
    private Map<String, Variable> referencedLocalVariables = Collections.emptyMap();
    private Map<String, Variable> referencedClassVariables = Collections.emptyMap();

    public VariableScope() {
        super();
    }

    public VariableScope(VariableScope parent) {
        this.parent = parent;
    }

    public VariableScope getParent() {
        return parent;
    }

    public boolean isRoot() {
        return parent == null;
    }

    /**
     * Non-null iff this scope corresponds to a class; as opposed to a method, "if" statement, block statement, etc.
     */
    public ClassNode getClassScope() {
        return classScope;
    }

    /**
     * Returns true iff this scope corresponds to a class; as opposed to a method, "if" statement, block statement, etc.
     */
    public boolean isClassScope() {
        return classScope != null;
    }

    public void setClassScope(ClassNode classScope) {
        this.classScope = classScope;
    }

    public boolean isInStaticContext() {
        return inStaticContext;
    }

    public void setInStaticContext(boolean inStaticContext) {
        this.inStaticContext = inStaticContext;
    }

    //

    public Variable getDeclaredVariable(String name) {
        return declaredVariables.get(name);
    }

    public Variable getReferencedLocalVariable(String name) {
        return referencedLocalVariables.get(name);
    }

    public Variable getReferencedClassVariable(String name) {
        return referencedClassVariables.get(name);
    }

    public boolean isReferencedLocalVariable(String name) {
        return referencedLocalVariables.containsKey(name);
    }

    public boolean isReferencedClassVariable(String name) {
        return referencedClassVariables.containsKey(name);
    }

    /**
     * Gets a map containing the variables declared in this scope. This map cannot be modified.
     *
     * @return a map containing the declared variable references
     */
    public Map<String, Variable> getDeclaredVariables() {
        if (declaredVariables == Collections.EMPTY_MAP) {
            return declaredVariables;
        } else {
            return Collections.unmodifiableMap(declaredVariables);
        }
    }

    /**
     * Gets a map containing the class variables referenced by this scope. This not can not be modified.
     *
     * @return a map containing the class variable references
     */
    public Map<String, Variable> getReferencedClassVariables() {
        if (referencedClassVariables == Collections.EMPTY_MAP) {
            return referencedClassVariables;
        } else {
            return Collections.unmodifiableMap(referencedClassVariables);
        }
    }

    public int getReferencedLocalVariablesCount() {
        return referencedLocalVariables.size();
    }

    /**
     * Gets an iterator for the declared class variables. The remove operation is not supported.
     *
     * @return an iterator for the declared variables
     */
    public Iterator<Variable> getDeclaredVariablesIterator() {
        return getDeclaredVariables().values().iterator();
    }

    /**
     * Gets an iterator for the referenced local variables. The remove operation *is* supported.
     *
     * @return an iterator for the referenced local variables
     */
    public Iterator<Variable> getReferencedLocalVariablesIterator() {
        return referencedLocalVariables.values().iterator();
    }

    /**
     * Gets an iterator for the referenced class variables. The remove operation is not supported.
     *
     * @return an iterator for the referenced class variables
     */
    public Iterator<Variable> getReferencedClassVariablesIterator() {
        return getReferencedClassVariables().values().iterator();
    }

    public void putDeclaredVariable(Variable var) {
        if (declaredVariables == Collections.EMPTY_MAP)
            declaredVariables = new LinkedHashMap<>();
        declaredVariables.put(var.getName(), var);
    }

    public void putReferencedLocalVariable(Variable var) {
        if (referencedLocalVariables == Collections.EMPTY_MAP)
            referencedLocalVariables = new LinkedHashMap<>();
        referencedLocalVariables.put(var.getName(), var);
    }

    public void putReferencedClassVariable(Variable var) {
        if (referencedClassVariables == Collections.EMPTY_MAP)
            referencedClassVariables = new LinkedHashMap<>();
        referencedClassVariables.put(var.getName(), var);
    }

    public Object removeReferencedClassVariable(String name) {
        if (referencedClassVariables.isEmpty()) {
            return null;
        } else {
            return referencedClassVariables.remove(name);
        }
    }

    //

    // TODO: implement Cloneable and override Object.clone()
    public VariableScope copy() {
        VariableScope copy = new VariableScope(parent);
        copy.classScope = classScope;
        copy.inStaticContext = inStaticContext;
        copy.resolvesDynamic = resolvesDynamic;
        if (!declaredVariables.isEmpty()) {
            copy.declaredVariables = new LinkedHashMap<>(declaredVariables);
        }
        if (!referencedLocalVariables.isEmpty()) {
            copy.referencedLocalVariables = new LinkedHashMap<>(referencedLocalVariables);
        }
        if (!referencedClassVariables.isEmpty()) {
            copy.referencedClassVariables = new LinkedHashMap<>(referencedClassVariables);
        }
        return copy;
    }
}
