// 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 com.google.common.collect.Sets;
import com.google.common.io.CharStreams;
import com.google.common.io.Closeables;
import com.google.dart.compiler.ast.DartNode;
import com.google.dart.compiler.ast.DartUnit;
import com.google.dart.compiler.ast.LibraryNode;
import com.google.dart.compiler.ast.LibraryUnit;
import com.google.dart.compiler.metrics.CompilerMetrics;
import com.google.dart.compiler.parser.DartParser;
import com.google.dart.compiler.resolver.CoreTypeProvider;
import com.google.dart.compiler.resolver.CoreTypeProviderImplementation;
import com.google.dart.compiler.resolver.Element;
import com.google.dart.compiler.resolver.ElementKind;
import com.google.dart.compiler.resolver.LibraryElement;
import com.google.dart.compiler.resolver.MemberBuilder;
import com.google.dart.compiler.resolver.Resolver;
import com.google.dart.compiler.resolver.Scope;
import com.google.dart.compiler.resolver.SupertypeResolver;
import com.google.dart.compiler.resolver.TopLevelElementBuilder;
import com.google.dart.compiler.type.TypeAnalyzer;

import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.net.URI;

class DeltaAnalyzer {
  private final SourceDelta delta;
  private final LibraryElement enclosingLibrary;
  private final CompilerConfiguration config;
  private final DartCompilerListener listener;
  private final CoreTypeProvider typeProvider;
  private final DartCompilerContext context;

  public DeltaAnalyzer(SourceDelta delta,
                       LibraryElement enclosingLibrary,
                       LibraryElement coreLibrary,
                       DartNode interestNode,
                       int interestStart,
                       int interestLength,
                       CompilerConfiguration config,
                       DartCompilerListener listener) {
    this.delta = delta;
    this.enclosingLibrary = enclosingLibrary;
    this.config = config;
    this.listener = listener;
    typeProvider = new CoreTypeProviderImplementation(coreLibrary.getScope(), listener);
    this.context = new Context();
  }

  public DartNode analyze() throws IOException {
    Source originalSource = delta.getSourceBefore();
    DartUnit unit = delta.getUnitAfter();
    if (unit == null) {
      DartSource source = delta.getSourceAfter();
      unit = getParser(source).parseUnit();
    }
    Scope scope = deltaLibraryScope(originalSource, unit);
    // We have to create supertypes and member elements for the entire unit. For example, if you're
    // doing code-completion, you are only interested in the current expression, but you may be
    // code-completing on a type that is defined outside the current class.
    new SupertypeResolver().exec(unit, context, typeProvider);
    new MemberBuilder().exec(unit, context, typeProvider);

    // The following two phases can be narrowed down to the interest area. We currently ignore the
    // interest area, but long term, we will need to narrow down to the interest area to handle
    // very large files.
    new Resolver(context, scope, typeProvider).exec(unit);
    new TypeAnalyzer().exec(unit, context, typeProvider);
    return unit;
  }

  private Scope deltaLibraryScope(Source originalSource, DartUnit unit) {
    // Create a library unit which holds the new unit.
    LibraryUnit libraryUnit = new LibraryUnit(makeLibrarySource("delta"));
    // Copy all the imports
    for (LibraryNode path : enclosingLibrary.getLibraryUnit().getImportPaths()) {
      libraryUnit.addImportPath(path);
    }
    for (LibraryUnit importUnit : enclosingLibrary.getLibraryUnit().getImportedLibraries()) {
      libraryUnit.addImport(importUnit, importUnit.getEntryNode());
    }
    libraryUnit.putUnit(unit);

    // Create top-level elements for the new unit.
    new TopLevelElementBuilder().exec(libraryUnit, context);
    new TopLevelElementBuilder().fillInLibraryScope(libraryUnit, listener);

    // Copy all the elements from the old library, except the ones declared in the original source.
    Scope scope = libraryUnit.getElement().getScope();
    for (Element member : enclosingLibrary.getMembers()) {
      if (member.getSourceInfo().getSource() != originalSource) {
        String name = member.getName();
        if (ElementKind.of(member) == ElementKind.LIBRARY) {
          name = "__library_" + ((LibraryElement) member).getLibraryUnit().getName();
        }
        scope.declareElement(name, member);
      }
    }
    return scope;
  }

  private LibrarySource makeLibrarySource(final String name) {
    final URI uri = URI.create(name);
    return new LibrarySource() {
      @Override
      public String getUniqueIdentifier() {
        return uri.toString();
      }

      @Override
      public URI getUri() {
        return uri;
      }

      @Override
      public Reader getSourceReader() {
        throw new AssertionError();
      }

      @Override
      public String getName() {
        return name;
      }

      @Override
      public long getLastModified() {
        throw new AssertionError();
      }

      @Override
      public boolean exists() {
        throw new AssertionError();
      }

      @Override
      public DartSource getSourceFor(String relPath) {
        return null;
      }

      @Override
      public LibrarySource getImportFor(String relPath) {
        return null;
      }
    };
  }

  private DartParser getParser(Source source) throws IOException {
    Reader r = source.getSourceReader();
    String sourceString = CharStreams.toString(r);
    Closeables.close(r, false);
    return new DartParser(source, sourceString, false, Sets.<String>newHashSet(), listener, null);
  }

  private class Context implements DartCompilerListener, DartCompilerContext {
    @Override
    public LibraryUnit getApplicationUnit() {
      throw new AssertionError();
    }

    @Override
    public LibraryUnit getAppLibraryUnit() {
      throw new AssertionError();
    }

    @Override
    public LibraryUnit getLibraryUnit(LibrarySource lib) {
      throw new AssertionError();
    }

    @Override
    public Reader getArtifactReader(Source source, String part, String extension) {
      throw new AssertionError();
    }

    @Override
    public URI getArtifactUri(DartSource source, String part, String extension) {
      throw new AssertionError();
    }

    @Override
    public Writer getArtifactWriter(Source source, String part, String extension) {
      throw new AssertionError();
    }

    @Override
    public boolean isOutOfDate(Source source, Source base, String extension) {
      throw new AssertionError();
    }

    @Override
    public CompilerMetrics getCompilerMetrics() {
      return null;
    }

    @Override
    public CompilerConfiguration getCompilerConfiguration() {
      return config;
    }

    @Override
    public LibrarySource getSystemLibraryFor(String importSpec) {
      throw new AssertionError();
    }

    @Override
    public void onError(DartCompilationError event) {
      listener.onError(event);
    }

    @Override
    public void unitAboutToCompile(DartSource source, boolean diet) {
    }

    @Override
    public void unitCompiled(DartUnit unit) {
    }
  }
}
