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

import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.dart.compiler.DartCompiler;
import com.google.dart.compiler.DartCompilerContext;
import com.google.dart.compiler.DartSource;
import com.google.dart.compiler.LibraryDeps;
import com.google.dart.compiler.LibrarySource;
import com.google.dart.compiler.resolver.Elements;
import com.google.dart.compiler.resolver.LibraryElement;

import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListMap;

/**
 * Represents the parsed source from a {@link LibrarySource}.
 */
public class LibraryUnit {
  private final LibrarySource libSource;
  private final LibraryNode selfSourcePath;
  private final List<LibraryNode> importPaths = Lists.newArrayList();
  private final List<LibraryNode> exportPaths = Lists.newArrayList();
  private final List<LibraryNode> sourcePaths = Lists.newArrayList();
  private final List<LibraryNode> nativePaths = Lists.newArrayList();

  private final Map<String, DartUnit> units = new ConcurrentSkipListMap<String, DartUnit>();
  private final List<LibraryImport> imports = Lists.newArrayList();
  private final List<LibraryExport> exports = Lists.newArrayList();

  private final LibraryElement element;

  private LibraryDeps deps;

  private LibraryNode entryNode;
  private DartUnit selfDartUnit;

  private String name;

  private DartExpression entryPoint;

  private int sourceCount;

  public void setName(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }

  public LibraryUnit(LibrarySource libSource) {
    assert libSource != null;
    this.libSource = libSource;
    element = Elements.libraryElement(this);

    // get the name part of the path, since it needs to be relative
    // TODO(jbrosenberg): change this to use lazy init
    // Note: We don't want an encoded relative path.
    String self = libSource.getUri().getSchemeSpecificPart();
    int lastSlash;
    if ((lastSlash = self.lastIndexOf('/')) > -1) {
      self = self.substring(lastSlash + 1);
    }
    selfSourcePath = new LibraryNode(self);
  }

  public void addImportPath(LibraryNode path) {
    assert path != null;
    importPaths.add(path);
  }
  
  public void addExportPath(LibraryNode path) {
    assert path != null;
    exportPaths.add(path);
  }

  public void addSourcePath(LibraryNode path) {
    assert path != null;
    sourcePaths.add(path);
    sourceCount++;
  }

  public int getSourceCount() {
    return sourceCount;
  }

  public void addNativePath(LibraryNode path) {
    assert path != null;
    nativePaths.add(path);
  }

  public void putUnit(DartUnit unit) {
    unit.setLibrary(this);
    units.put(unit.getSourceName(), unit);
  }

  public DartUnit getUnit(String sourceName) {
    return units.get(sourceName);
  }

  public void addImport(LibraryUnit unit, LibraryNode node) {
    if (unit != null) {
      if (node != null) {
        imports.add(new LibraryImport(unit, node.getPrefix(), node.getCombinators()));
      } else {
        imports.add(new LibraryImport(unit, null, ImmutableList.<ImportCombinator> of()));
      }
    }
  }
  
  public void addExport(LibraryUnit unit, LibraryNode node) {
    if (unit != null) {
      if (node != null) {
        exports.add(new LibraryExport(node.getSourceInfo(), unit, node.getCombinators()));
      }
    }
  }

  public Collection<LibraryUnit> getLibrariesWithPrefix(String prefixToMatch) {
    List<LibraryUnit> result = Lists.newArrayList();
    for (LibraryImport libraryImport : imports) {
      if (Objects.equal(libraryImport.getPrefix(), prefixToMatch)) {
        result.add(libraryImport.getLibrary());
      }
    }
    return result;
  }

  public LibraryElement getElement() {
    return element;
  }

  public Iterable<DartUnit> getUnits() {
    return units.values();
  }

  public Iterable<LibraryImport> getImports() {
    return imports;
  }
  
  public List<LibraryExport> getExports() {
    return exports;
  }

  public Iterable<LibraryUnit> getImportedLibraries() {
    LinkedHashSet<LibraryUnit> libraries = Sets.newLinkedHashSet();
    for (LibraryImport libraryImport : imports) {
      libraries.add(libraryImport.getLibrary());
    }
    return libraries;
  }

  public boolean hasImport(LibraryUnit unit) {
    for (LibraryImport libraryImport : imports) {
      if (libraryImport.getPrefix() == null && Objects.equal(libraryImport.getLibrary(), unit)) {
        return true;
      }
    }
    return false;
//    return imports.contains(new LibraryImport(unit, null, ImmutableList.<ImportCombinator> of()));
  }

  public DartExpression getEntryPoint() {
    return entryPoint;
  }

  public void setEntryPoint(DartExpression entry) {
    this.entryPoint = entry;
  }

  public DartUnit getSelfDartUnit() {
    return this.selfDartUnit;
  }

  public void setSelfDartUnit(DartUnit unit) {
    this.selfDartUnit = unit;
    // set DartObsoleteMetadata for LibraryElement
    if (unit != null) {
      List<DartDirective> directives = unit.getDirectives();
      if (!directives.isEmpty() && directives.get(0) instanceof DartLibraryDirective) {
        DartLibraryDirective libraryDirective = (DartLibraryDirective) directives.get(0);
        Elements.setLibraryMetadata(element, libraryDirective.getObsoleteMetadata());
      }
    }
  }

  /**
   * Return a collection of paths to {@link LibrarySource}s upon which this library or application
   * depends.
   * 
   * @return the paths (not <code>null</code>, contains no <code>null</code>)
   */
  public Iterable<LibraryNode> getImportPaths() {
    return importPaths;
  }
  
  public Iterable<LibraryNode> getExportPaths() {
    return exportPaths;
  }

  /**
   * Return all prefixes used by this library.
   */
  public Set<String> getPrefixes() {
    Set<String> result = Sets.newTreeSet();
    for (LibraryImport libraryImport : imports) {
      String prefix = libraryImport.getPrefix();
      if (prefix != null) {
        result.add(prefix);
      }
    }
    return result;
  }

  /**
   * Return the path for dart source that corresponds to the same dart file as this library unit.
   * This is added to the set of sourcePaths for this unit.
   * 
   * @return the self source path for this unit.
   */
  public LibraryNode getSelfSourcePath() {
    return selfSourcePath;
  }

  /**
   * Answer the source associated with this unit
   * 
   * @return the library source (not <code>null</code>)
   */
  public LibrarySource getSource() {
    return libSource;
  }

  /**
   * Return a collection of paths to {@link DartSource}s that are included in this library or
   * application.
   * 
   * @return the paths (not <code>null</code>, contains no <code>null</code>)
   */
  public Iterable<LibraryNode> getSourcePaths() {
    return sourcePaths;
  }

  /**
   * Returns a collection of paths to native {@link DartSource}s that are included in this library.
   * 
   * @return the paths (not <code>null</code>, contains no <code>null</code>)
   */
  public Iterable<LibraryNode> getNativePaths() {
    return nativePaths;
  }

  /**
   * Return the declared entry method, if any
   * 
   * @return the entry method or <code>null</code> if not defined
   */
  public LibraryNode getEntryNode() {
    return entryNode;
  }

  /**
   * Set the declared entry method.
   * 
   * @param libraryNode the entry method or <code>null</code> if none
   */
  public void setEntryNode(LibraryNode libraryNode) {
    this.entryNode = libraryNode;
  }

  /**
   * Gets the dependencies associated with this library. If no dependencies artifact exists, or the
   * file is invalid, it will return an empty deps object.
   */
  public LibraryDeps getDeps(DartCompilerContext context) throws IOException {
    if (deps != null) {
      return deps;
    }

    Reader reader = context.getArtifactReader(libSource, "", DartCompiler.EXTENSION_DEPS);
    if (reader != null) {
      deps = LibraryDeps.fromReader(reader);
      reader.close();
    }

    if (deps == null) {
      deps = new LibraryDeps();
    }
    return deps;
  }

  /**
   * Writes this library's associated dependencies.
   */
  public void writeDeps(DartCompilerContext context) throws IOException {
    Writer writer = context.getArtifactWriter(libSource, "", DartCompiler.EXTENSION_DEPS);
    deps.write(writer);
    writer.close();
  }
}
