// Copyright 2014 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.packages;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;

/**
 * Checked exception for analysis-time errors, which can store the errors for later reporting.
 *
 * <p>It's more robust for a method to throw this exception than expecting a
 * {@link RuleErrorConsumer} object (which may be null).
 */
public final class AnalysisIssues extends Exception {

  /**
   * An error entry.
   *
   * <p>{@link AnalysisIssues} can accumulate multiple of these, and report all of them at once.
   */
  public static final class Entry {
    private final String attribute;
    private final String messageTemplate;
    private final Object[] arguments;

    private Entry(@Nullable String attribute, String messageTemplate, Object... arguments) {
      this.attribute = attribute;
      this.messageTemplate = messageTemplate;
      this.arguments = arguments;
    }

    private void reportTo(RuleErrorConsumer errors) {
      String msg = String.format(messageTemplate, arguments);
      if (attribute == null) {
        errors.ruleError(msg);
      } else {
        errors.attributeError(attribute, msg);
      }
    }

    private void reportTo(StringBuilder sb) {
      String msg = String.format(messageTemplate, arguments);
      if (attribute == null) {
        sb.append("ERROR: ").append(msg);
      } else {
        sb.append("ERROR: in attribute \"").append(attribute).append("\": ").append(msg);
      }
    }

    @Override
    public String toString() {
      if (attribute == null) {
        return String.format("ERROR: " + messageTemplate, arguments);
      } else {
        List<Object> args = new ArrayList<>();
        args.add(attribute);
        Collections.addAll(args, arguments);
        return String.format("ERROR in '%s': " + messageTemplate, args.toArray());
      }
    }
  }

  private final ImmutableList<Entry> entries;

  public AnalysisIssues(Entry entry) {
    this.entries = ImmutableList.of(Preconditions.checkNotNull(entry));
  }

  public AnalysisIssues(Collection<Entry> entries) {
    this.entries = ImmutableList.copyOf(Preconditions.checkNotNull(entries));
  }

  /**
   * Creates a attribute error entry that will be added to a {@link AnalysisIssues} later.
   */
  public static Entry attributeError(String attribute, String messageTemplate,
      Object... arguments) {
    return new Entry(attribute, messageTemplate, arguments);
  }

  public static Entry ruleError(String messageTemplate, Object... arguments) {
    return new Entry(null, messageTemplate, arguments);
  }

  /**
   * Report all accumulated errors and warnings to the given consumer object.
   */
  public void reportTo(RuleErrorConsumer errors) {
    Preconditions.checkNotNull(errors);
    for (Entry e : entries) {
      e.reportTo(errors);
    }
  }

  @Nullable
  private String asString() {
    if (entries == null) {
      return null;
    }

    StringBuilder sb = new StringBuilder();
    for (Entry e : entries) {
      e.reportTo(sb);
    }
    return sb.toString();
  }

  @Override
  public String getMessage() {
    return asString();
  }

  @Override
  public String toString() {
    String s = asString();
    return s == null ? "" : s;
  }
}
