// 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.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(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() {
    Set<LibraryUnit> libraries = Sets.newHashSet();
    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();
  }
}
