// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

package com.google.dart.compiler.resolver;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Sets;
import com.google.dart.compiler.ast.DartBlock;
import com.google.dart.compiler.ast.DartIdentifier;
import com.google.dart.compiler.ast.DartVariableStatement;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * A scope used by {@link Resolver}.
 */
public class Scope {

  private final Map<String, Element> elements = new LinkedHashMap<String, Element>();
  private final Set<String> declaredButNotReachedVariables = Sets.newHashSet();
  private final Scope parent;
  private final String name;
  private List<LabelElement> labels;
  private LibraryElement library;
  private boolean stateReady;

  @VisibleForTesting
  public Scope(String name, LibraryElement library, Scope parent) {
    this.name = name;
    this.parent = parent;
    this.library = library;
  }

  @VisibleForTesting
  public Scope(String name, LibraryElement element) {
    this(name, element, null);
  }

  public void clear() {
    elements.clear();
  }

  public Element declareElement(String name, Element element) {
    return elements.put(name, element);
  }

  public Element findLocalElement(String name) {
    return elements.get(name);
  }

  public Element findElement(LibraryElement fromLibrary, String name) {
    Element element = null;
    // Only lookup a private name in this scope if we are in the correct library
    // or we are ignoring libraries (i.e., fromLibrary == null).
    if (fromLibrary == null
        || !DartIdentifier.isPrivateName(name)
        || fromLibrary.equals(library)) {
      element = findLocalElement(name);
    }
    if (element == null) {
      if (parent != null) {
        element = parent.findElement(fromLibrary, name);
      } else {
        element = null;
      }
    }
    return element;
  }

  public LibraryElement getLibrary() {
    return library;
  }

  public Element findLabel(String targetName, MethodElement innermostFunction) {
    if (labels != null) {
      for (LabelElement label : labels) {
        if (label.getName().equals(targetName)
          && innermostFunction == label.getEnclosingFunction()) {
          return label;
        }
      }
    }
    return parent == null ? null :
      parent.findLabel(targetName, innermostFunction);
  }

  public boolean hasLocalLabel(String labelName) {
    if (labels != null) {
      for (LabelElement label : labels) {
        if (label.getName().equals(labelName)) {
            return true;
        }
      }
    }
    return false;
  }
  
  public void markStateReady() {
    this.stateReady = true;
  }
  
  public boolean isStateReady() {
    return stateReady;
  }

  public Map<String, Element> getElements() {
    return elements;
  }

  /**
   * @return <code>true</code> if local variable with given name is declared in the lexical context
   *         of {@link DartBlock}, but corresponding {@link DartVariableStatement} is not visited
   *         yet. So, using this variable is error.
   */
  public boolean isDeclaredButNotReachedVariable(String name) {
    return declaredButNotReachedVariables.contains(name);
  }

  /**
   * @see #isDeclaredButNotReachedVariable(String)
   */
  public void addDeclaredButNotReachedVariable(String name) {
    declaredButNotReachedVariables.add(name);
  }

  /**
   * @see #isDeclaredButNotReachedVariable(String)
   */
  public void removeDeclaredButNotReachedVariable(String name) {
    declaredButNotReachedVariables.remove(name);
  }

  public String getName() {
    return name;
  }

  public Scope getParent() {
    return parent;
  }

  public boolean isClear() {
    return elements.size() == 0;
  }

  public void addLabel(LabelElement label) {
    if (labels == null) {
      labels = new ArrayList<LabelElement>();
    }
    labels.add(label);
  }

  @Override
  public String toString() {
    return getName() + " : \n" + elements.toString();
  }
}
