// Copyright (c) 2017, the R8 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.android.tools.r8.utils;

import static com.android.tools.r8.DiagnosticsLevel.ERROR;
import static com.android.tools.r8.DiagnosticsLevel.INFO;
import static com.android.tools.r8.DiagnosticsLevel.WARNING;

import com.android.tools.r8.Diagnostic;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.DiagnosticsLevel;
import com.android.tools.r8.errors.Unreachable;
import java.util.ArrayList;
import java.util.List;

public class Reporter implements DiagnosticsHandler {

  private static class DiagnosticsLevelMapping {
    private final DiagnosticsLevel from;
    private final DiagnosticsLevel to;
    private final String diagnosticsClassName;

    public DiagnosticsLevelMapping(
        DiagnosticsLevel from, DiagnosticsLevel to, String diagnosticsClassName) {
      this.from = from;
      this.to = to;
      this.diagnosticsClassName = diagnosticsClassName;
    }

    public DiagnosticsLevel map(DiagnosticsLevel level, Diagnostic diagnostic) {
      if (level != from) {
        return level;
      }
      if (diagnosticsClassName.length() == 0
          || diagnosticsClassName.equals(diagnostic.getClass().getSimpleName())
          || diagnosticsClassName.equals(diagnostic.getClass().getTypeName())) {
        return to;
      }
      // Some diagnostics are exposed as interfaces, and implemented by internal implementations.
      for (Class<?> clazz : diagnostic.getClass().getInterfaces()) {
        if (diagnosticsClassName.equals(clazz.getSimpleName())
            || diagnosticsClassName.equals(clazz.getTypeName())) {
          return to;
        }
      }
      return level;
    }
  }

  private final DiagnosticsHandler clientHandler;
  private final List<DiagnosticsLevelMapping> diagnosticsLevelMapping = new ArrayList<>();
  private AbortException abort = null;

  public Reporter() {
    this(new DiagnosticsHandler() {});
  }

  public Reporter(DiagnosticsHandler clientHandler) {
    this.clientHandler = clientHandler;
  }

  private void handleDiagnostic(DiagnosticsLevel level, Diagnostic diagnostic) {
    // To avoid having an entry for fatal error in the public  API enum use null to signal
    // fatal error internally.
    if (level != null) {
      DiagnosticsLevel modifiedLevel = clientHandler.modifyDiagnosticsLevel(level, diagnostic);
      level = modifiedLevel != null ? modifiedLevel : level;
      level = mapDiagnosticsLevel(level, diagnostic);
    } else {
      level = ERROR;
    }
    switch (level) {
      case INFO:
        clientHandler.info(diagnostic);
        break;
      case WARNING:
        clientHandler.warning(diagnostic);
        break;
      case ERROR:
        abort = new AbortException(diagnostic);
        clientHandler.error(diagnostic);
        break;
      default:
        throw new Unreachable();
    }
  }

  @Override
  public synchronized void info(Diagnostic info) {
    handleDiagnostic(INFO, info);
  }

  public void info(String message) {
    info(new StringDiagnostic(message));
  }

  @Override
  public synchronized void warning(Diagnostic warning) {
    handleDiagnostic(WARNING, warning);
  }

  public void warning(String message) {
    warning(new StringDiagnostic(message));
  }

  @Override
  public synchronized void error(Diagnostic error) {
    handleDiagnostic(ERROR, error);
  }

  public void error(String message) {
    error(new StringDiagnostic(message));
  }

  /**
   * @throws AbortException always.
   */
  public RuntimeException fatalError(String message) {
    throw fatalError(new StringDiagnostic(message));
  }

  /**
   * @throws AbortException always.
   */
  public RuntimeException fatalError(Diagnostic error) {
    handleDiagnostic(null, error);
    throw abort;
  }

  /** @throws AbortException if any error was reported. */
  public synchronized void failIfPendingErrors() {
    if (abort != null) {
      throw new RuntimeException(abort);
    }
  }

  private DiagnosticsLevel mapDiagnosticsLevel(DiagnosticsLevel level, Diagnostic diagnostic) {
    for (DiagnosticsLevelMapping diagnosticsLevelMapping : diagnosticsLevelMapping) {
      level = diagnosticsLevelMapping.map(level, diagnostic);
    }
    return level;
  }

  public void addDiagnosticsLevelMapping(
      DiagnosticsLevel from, String diagnosticsClassName, DiagnosticsLevel to) {
    diagnosticsLevelMapping.add(new DiagnosticsLevelMapping(from, to, diagnosticsClassName));
  }
}
