// 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.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.dart.compiler.ast.DartUnit;
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.Elements;
import com.google.dart.compiler.resolver.ResolverErrorCode;
import com.google.dart.compiler.resolver.TypeErrorCode;

import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * An overall context for the Dart compiler providing an adapter and forwarding
 * mechanism for to both {@link DartArtifactProvider} and
 * {@link DartCompilerListener}. This is an internal compiler construct and as
 * such should not be instantiated or subclassed by those outside the compiler
 * itself.
 */
final class DartCompilerMainContext implements DartCompilerListener, DartCompilerContext {

  private final LibrarySource lib;
  private final DartArtifactProvider provider;
  private final DartCompilerListener listener;
  private final Map<Source, List<DartCompilationError>> errors = Maps.newHashMap();
  private final AtomicInteger errorCount = new AtomicInteger(0);
  private final AtomicInteger warningCount = new AtomicInteger(0);
  private final AtomicInteger typeErrorCount = new AtomicInteger(0);
  private final AtomicBoolean filesHaveChanged = new AtomicBoolean();
  // declared volatile for thread-safety
  private volatile LibraryUnit appLibraryUnit = null;

  private final CompilerConfiguration compilerConfiguration;

  DartCompilerMainContext(LibrarySource lib, DartArtifactProvider provider,
      DartCompilerListener listener,
      CompilerConfiguration compilerConfiguration) {
    this.lib = lib;
    this.provider = provider;
    this.listener = listener;
    this.compilerConfiguration = compilerConfiguration;
  }

  @Override
  public void onError(DartCompilationError event) {
    // problems in dart:core are not interesting
    // http://code.google.com/p/dart/issues/detail?id=7128
    if (Elements.isCoreLibrarySource(event.getSource())) {
      ErrorCode ec = event.getErrorCode();
      if (ec == ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER
          || ec == TypeErrorCode.ASSERT_BOOL
          || ec == TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE
          || ec == TypeErrorCode.FOR_IN_WITH_INVALID_ITERATOR_RETURN_TYPE
          || ec == TypeErrorCode.OPERATOR_EQUALS_BOOL_RETURN_TYPE
          || ec == TypeErrorCode.CANNOT_OVERRIDE_TYPED_MEMBER
          || ec == TypeErrorCode.CANNOT_OVERRIDE_METHOD_NOT_SUBTYPE
          || ec == TypeErrorCode.OPERATOR_WRONG_OPERAND_TYPE) {
        return;
      }
    }

    // Remember error.
    {
      Source source = event.getSource();
      if (source != null) {
        List<DartCompilationError> sourceErrors = errors.get(source);
        if (sourceErrors == null) {
          sourceErrors = Lists.newArrayList();
          errors.put(source, sourceErrors);
        }
        sourceErrors.add(event);
      }
    }
    // Increment counters.
    if (event.getErrorCode().getSubSystem() == SubSystem.STATIC_TYPE) {
      incrementTypeErrorCount();
    }
    if (event.getErrorCode().getErrorSeverity() == ErrorSeverity.ERROR) {
      incrementErrorCount();
    } else if (event.getErrorCode().getErrorSeverity() == ErrorSeverity.WARNING) {
      incrementWarningCount();
    }
    // Notify listener.
    listener.onError(event);
  }

  @Override
  public LibraryUnit getApplicationUnit() {
    return getAppLibraryUnit();
  }

  @Override
  public LibraryUnit getAppLibraryUnit() {
    // use double-checked looking pattern with use of volatile
    if (appLibraryUnit == null) {
      synchronized (this) {
        if (appLibraryUnit == null) {
          try {
            appLibraryUnit = new DartParser(lib, DartParser.read(lib), false,
                Sets.<String> newHashSet(), DartCompilerListener.EMPTY, null).preProcessLibraryDirectives(lib);
          } catch (IOException e) {
            onError(new DartCompilationError(lib, DartCompilerErrorCode.IO, e.getMessage()));
            return null;
          }
        }
      }
    }
    return appLibraryUnit;
  }

  @Override
  public Reader getArtifactReader(Source source, String part, String extension)
      throws IOException {
    return provider.getArtifactReader(source, part, extension);
  }

  @Override
  public URI getArtifactUri(DartSource source, String part, String extension) {
    return provider.getArtifactUri(source, part, extension);
  }

  @Override
  public Writer getArtifactWriter(Source source, String part, String extension)
      throws IOException {
    return provider.getArtifactWriter(source, part, extension);
  }

  /**
   * @return the {@link DartCompilationError}s found in the given {@link Source}.
   */
  public List<DartCompilationError> getSourceErrors(Source source) {
    List<DartCompilationError> sourceErrors = errors.get(source);
    if (sourceErrors != null) {
      return sourceErrors;
    }
    return Collections.emptyList();
  }

  public int getErrorCount() {
    return errorCount.get();
  }

  public int getWarningCount() {
    return warningCount.get();
  }

  public int getTypeErrorCount() {
    return typeErrorCount.get();
  }

  @Override
  public LibraryUnit getLibraryUnit(LibrarySource libSrc) {
    if (libSrc == lib) {
      return getApplicationUnit();
    }
    try {
      return new DartParser(libSrc, DartParser.read(libSrc), false,
          Sets.<String> newHashSet(), listener, null).preProcessLibraryDirectives(libSrc);
    } catch (IOException e) {
      onError(new DartCompilationError(libSrc, DartCompilerErrorCode.IO, e.getMessage()));
      return null;
    }
  }

  @Override
  public boolean isOutOfDate(Source source, Source base, String extension) {
    return provider.isOutOfDate(source, base, extension);
  }

  protected void incrementErrorCount() {
    errorCount.incrementAndGet();
  }

  protected void incrementWarningCount() {
    warningCount.incrementAndGet();
  }

  protected void incrementTypeErrorCount() {
    typeErrorCount.incrementAndGet();
  }

  @Override
  public CompilerMetrics getCompilerMetrics() {
    return compilerConfiguration.getCompilerMetrics();
  }

  public void setFilesHaveChanged() {
    filesHaveChanged.set(true);
  }

  public boolean getFilesHaveChanged() {
    return filesHaveChanged.get();
  }

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

  /**
   * Return the system library corresponding to the specified "dart:<libname>" spec.
   */
  @Override
  public LibrarySource getSystemLibraryFor(String importSpec) {
    return compilerConfiguration.getSystemLibraryFor(importSpec);
  }

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

  @Override
  public void unitCompiled(DartUnit unit) {
    listener.unitCompiled(unit);
  }
}
