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

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;


/**
 * Manages the collection of {@link SystemLibrary}s.
 */
public class PackageLibraryManager {

  public static class NotADartShortUriException extends RuntimeException {
    private static final long serialVersionUID = 1L;

    public NotADartShortUriException(String uriString) {
      super("Expected dart:<short name>, got: " + uriString);
    }

    public NotADartShortUriException(URI uri) {
      super("Expected dart:<short name>, got: " + uri.toString());
    }
  }

  /**
   * The "any" platform is meant to have definitions for all known dart system libraries.
   * Other implementations may only contain a subset.
   */
  public static final String DEFAULT_PLATFORM = "any";
  public static final File DEFAULT_SDK_PATH = new File(System.getProperty(
      "com.google.dart.sdk", "../"));
  
  public static final File DEFAULT_PACKAGE_ROOT = new File("packages");
  public static final List<File> DEFAULT_PACKAGE_ROOTS = Arrays.asList(new File[] {DEFAULT_PACKAGE_ROOT});

  public static final String PACKAGE_SCHEME = "package";
  public static final String PACKAGE_SCHEME_SPEC = "package:";

  public static final String DART_SCHEME = "dart";
  public static final String DART_SCHEME_SPEC = "dart:";
  

  /**
   * Answer <code>true</code> if the string is a dart spec
   */
  public static boolean isDartSpec(String spec) {
    return spec != null && spec.startsWith(DART_SCHEME_SPEC);
  }

  /**
   * Answer <code>true</code> if the specified URI has a "dart" scheme
   */
  public static boolean isDartUri(URI uri) {
    return uri != null && DART_SCHEME.equals(uri.getScheme());
  }

  /**
   * Answer <code>true</code> if the string is a package spec
   */
  public static boolean isPackageSpec(String spec) {
    return spec != null && spec.startsWith(PACKAGE_SCHEME_SPEC);
  }

  /**
   * Answer <code>true</code> if the specified URI has a "package" scheme
   */
  public static boolean isPackageUri(URI uri) {
    return uri != null && PACKAGE_SCHEME.equals(uri.getScheme());
  }

  private static SystemLibraryManager SDK_LIBRARY_MANAGER;
  
  private List<File> packageRoots = new ArrayList<File>();
  private List<URI> packageRootsUri = new ArrayList<URI>(); 

  public PackageLibraryManager() {
    this(DEFAULT_SDK_PATH, DEFAULT_PLATFORM);
  }

  public PackageLibraryManager(File sdkPath, String platformName) {
    this(new FileBasedSystemLibraryProvider(sdkPath));
  }

  public PackageLibraryManager(SystemLibraryProvider libraryProvider) {
    initLibraryManager(libraryProvider);
    setPackageRoots(DEFAULT_PACKAGE_ROOTS);
  }
  
  protected void initLibraryManager(SystemLibraryProvider libraryProvider) {
    if (SDK_LIBRARY_MANAGER == null) {
      SDK_LIBRARY_MANAGER = new SystemLibraryManager(libraryProvider);
    }
  }


  /**
   * Expand a relative or short URI (e.g. "dart:html") which is implementation independent to its
   * full URI (e.g. "dart://html/com/google/dart/htmllib/html.dart").
   *
   * @param uri the relative URI
   * @return the expanded URI
   *  or the original URI if it could not be expanded
   *  or null if the uri is of the form "dart:<libname>" but does not correspond to a system library
   */
  public URI expandRelativeDartUri(URI uri) throws AssertionError {
    if (isDartUri(uri)) {
      return SDK_LIBRARY_MANAGER.expandRelativeDartUri(uri);
    } 
    if (isPackageUri(uri)){
      String host = uri.getHost();
      if (host == null) {
        String spec = uri.getSchemeSpecificPart();
        if (!spec.startsWith("//")){
          try {
            if (spec.startsWith("/")){
              // TODO(keertip): fix to handle spaces
              uri = new URI(PACKAGE_SCHEME + ":/" + spec);
            } else {
              uri = new URI(PACKAGE_SCHEME + "://" + spec);
            } 
          } catch (URISyntaxException e) {
            throw new AssertionError(e);
          }
        }       
      }
    }
    return uri;
  }

 
  
  /**
   * Given an absolute file URI (e.g. "file:/some/install/directory/dart-sdk/lib/core/bool.dart"),
   *  answer the corresponding dart: URI (e.g. "dart://core/bool.dart") for that file URI,
   *  or <code>null</code> if the file URI does not map to a dart: URI 
   * @param fileUri the file URI
   * @return the dart URI or <code>null</code>
   */
  public URI getRelativeUri(URI fileUri) {
    // TODO (danrubel): does not convert dart: libraries outside the dart-sdk/lib directory
    if (fileUri == null || !fileUri.getScheme().equals("file")) {
      return null;
    }
   
    URI relativeUri = SDK_LIBRARY_MANAGER.getRelativeUri(fileUri);
    if (relativeUri != null){
      return relativeUri;
    }
    
    for (URI rootUri : packageRootsUri){
      relativeUri = rootUri.relativize(fileUri);
        if (relativeUri.getScheme() == null) {
          try {
            return new URI(null, null, "package://" + relativeUri.getPath(), null, null);
          } catch (URISyntaxException e) {
        //$FALL-THROUGH$
        }
      }
    }
    return null;
  }

  /**
   * Given a package URI (package:foo/foo.dart), convert it into a file system URI.
   */
  public URI resolvePackageUri(String packageUriRef) {
    if (packageUriRef.startsWith(PACKAGE_SCHEME_SPEC)) {
      String relPath = packageUriRef.substring(PACKAGE_SCHEME_SPEC.length());
      if (relPath.startsWith("/")){
        relPath = relPath.replaceAll("^\\/+", "");
      }
      for (URI rootUri : packageRootsUri){
        URI fileUri = rootUri.resolve(relPath);
        File file = new File(fileUri);
        if (file.exists()){
          try {
            return file.getCanonicalFile().toURI();
          } catch (IOException e) {
            file.toURI();
          }
        }
      }
      // don't return null for package scheme
      return packageRootsUri.get(0).resolve(relPath);
    }
   return null; 
  }

  /**
   * Answer the original "dart:<libname>" URI for the specified resolved URI or <code>null</code> if
   * it does not map to a short URI.
   */
  public URI getShortUri(URI uri) {
    URI shortUri = SDK_LIBRARY_MANAGER.getShortUri(uri);
    if (shortUri != null){
      return shortUri;
    }
    shortUri = getRelativeUri(uri);
    if (shortUri != null){
      try {
        if (shortUri.getHost() != null){
          return new URI(null, null, shortUri.getScheme() + ":" +  shortUri.getHost() + shortUri.getPath(),null, null);
        }
        else {
          return new URI(null, null, shortUri.getScheme() + ":" +  shortUri.getSchemeSpecificPart(), null, null);
        }
      } catch (URISyntaxException e) {
      }
    }
    return null;
  }

  /**
   * Expand a relative or short URI (e.g. "dart:html") which is implementation independent to its
   * full URI (e.g. "dart://html/com/google/dart/htmllib/html.dart") and then translate that URI to
   * a "file:"  URI (e.g.
   * "file:/some/install/directory/com/google/dart/htmllib/html.dart").
   *
   * @param uri the original URI
   * @return the expanded and translated URI, which may be <code>null</code> and may not exist
   * @exception RuntimeException if the URI is a "dart" scheme, but does not map to a defined system
   *     library
   */
  public URI resolveDartUri(URI uri) {
    return translateDartUri(expandRelativeDartUri(uri));
  }
  
  
  public List<File> getPackageRoots(){
    return packageRoots;
  }
  
  
  public void setPackageRoots(List<File> roots){
    if (roots == null || roots.isEmpty()){
      roots = DEFAULT_PACKAGE_ROOTS;
    }
    packageRoots.clear();
    for (File file : roots){   
      packageRoots.add(file.getAbsoluteFile());
    }   
    packageRootsUri.clear();
    for (File file : roots){
      packageRootsUri.add(file.toURI());
    }
  }
  
  /**
   * Translate the URI from dart://[host]/[pathToLib] (e.g. dart://html/html.dart)
   * to a "file:" URI (e.g. "file:/some/install/directory/html.dart")
   *
   * @param uri the original URI
   * @return the translated URI, which may be <code>null</code> and may not exist
   * @exception RuntimeException if the URI is a "dart" scheme,
   *     but does not map to a defined system library
   */
  public URI translateDartUri(URI uri) {
    if (isDartUri(uri)) {
     return SDK_LIBRARY_MANAGER.translateDartUri(uri);
    } 
    if (isPackageUri(uri)){   
      URI fileUri;
      for (URI rootUri : packageRootsUri){
        fileUri = getResolvedPackageUri(uri, rootUri);
        File file  = new File(fileUri);
        if (file.exists()){
          try {
            return file.getCanonicalFile().toURI();
          } catch (IOException e) {
            return file.toURI();
          }
        }
      }
      // resolve against first package root
      fileUri = getResolvedPackageUri(uri, packageRootsUri.get(0));
      return fileUri;
    }
    return uri;
  }

  
  /**
   * Given a uri, resolve against the list of package roots, used to find generated files
   * @return uri - resolved uri if file exists, else return given uri 
   */
  public URI findExistingFileInPackages(URI fileUri){
    
    URI resolvedUri = getRelativeUri(fileUri);
    if (isPackageUri(resolvedUri)){
      resolvedUri = resolvePackageUri(resolvedUri.toString());
      return resolvedUri;
    }
    return fileUri;
  }

  /**
   * Resolves the given uri against the package root uri
   */
  private URI getResolvedPackageUri(URI uri, URI packageRootUri) {
    URI fileUri;
    // TODO(keertip): Investigate further
    // if uri.getHost() returns null, then it is resolved right
    // so use uri.getAuthority to resolve
    // package://third_party/dart_lang/lib/unittest/unittest.dart
    if (uri.getHost() != null){
      fileUri =  packageRootUri.resolve(uri.getHost() + uri.getPath());
    } else {
      fileUri = packageRootUri.resolve(uri.getAuthority() + uri.getPath());
    }
    return fileUri;
  }

  /**
   * Answer a collection of all bundled library URL specs (e.g. "dart:html").
   *
   * @return a collection of specs (not <code>null</code>, contains no <code>null</code>s)
   */
  public Collection<String> getAllLibrarySpecs() {
    return SDK_LIBRARY_MANAGER.getAllLibrarySpecs();
  }
  
  protected SystemLibrary[] getDefaultLibraries() {
    return SDK_LIBRARY_MANAGER.getDefaultLibraries(); 
  }
  
  public Collection<SystemLibrary> getSystemLibraries(){
    return SDK_LIBRARY_MANAGER.getAllSystemLibraries();
  }

  /**
   * Check if this URI denotes a patch file.
   */
  public static boolean isPatchFile(File file) {
    return SDK_LIBRARY_MANAGER.isPatchFile(file.toURI());
  } 
  
}
