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

import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
import com.android.tools.r8.utils.ExceptionDiagnostic;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

/** Interface for receiving String resource. */
public interface StringConsumer {

  /**
   * Callback to receive a String resource.
   *
   * <p>The consumer is expected not to throw, but instead report any errors via the diagnostics
   * {@param handler}. If an error is reported via {@param handler} and no exceptions are thrown,
   * then the compiler guaranties to exit with an error.
   *
   * @param string String resource.
   * @param handler Diagnostics handler for reporting.
   */
  void accept(String string, DiagnosticsHandler handler);

  static EmptyConsumer emptyConsumer() {
    return EmptyConsumer.EMPTY_CONSUMER;
  }

  /** Empty consumer to request the production of the resource but ignore its value. */
  class EmptyConsumer implements StringConsumer {

    private static final EmptyConsumer EMPTY_CONSUMER = new EmptyConsumer();

    @Override
    public void accept(String string, DiagnosticsHandler handler) {
      // Ignore content.
    }
  }

  /** Forwarding consumer to delegate to an optional existing consumer. */
  class ForwardingConsumer implements StringConsumer {

    private final StringConsumer consumer;

    /** @param consumer Consumer to forward to, if null, nothing will be forwarded. */
    public ForwardingConsumer(StringConsumer consumer) {
      this.consumer = consumer;
    }

    @Override
    public void accept(String string, DiagnosticsHandler handler) {
      if (consumer != null) {
        consumer.accept(string, handler);
      }
    }
  }

  /** File consumer to write contents to a file-system file. */
  class FileConsumer extends ForwardingConsumer {

    private final Path outputPath;
    private Charset encoding = StandardCharsets.UTF_8;

    /** Consumer that writes to {@param outputPath}. */
    public FileConsumer(Path outputPath) {
      this(outputPath, null);
    }

    /** Consumer that forwards to {@param consumer} and also writes to {@param outputPath}. */
    public FileConsumer(Path outputPath, StringConsumer consumer) {
      super(consumer);
      this.outputPath = outputPath;
    }

    /** Get the output path that the consumer will write to. */
    public Path getOutputPath() {
      return outputPath;
    }

    /** Set the output encoding. Defaults to UTF8. */
    public void setEncoding(Charset encoding) {
      assert encoding != null;
      this.encoding = encoding;
    }

    /** Get the output encoding. Defaults to UTF8. */
    public Charset getEncoding() {
      return encoding;
    }

    @Override
    public void accept(String string, DiagnosticsHandler handler) {
      super.accept(string, handler);
      try {
        Files.write(outputPath, string.getBytes(encoding));
      } catch (IOException e) {
        Origin origin = new PathOrigin(outputPath);
        handler.error(new ExceptionDiagnostic(e, origin));
      }
    }
  }

  /**
   * Stream consumer to write contents to an output stream.
   *
   * <p>Note: No close events are given to this stream so it should either be a permanent stream or
   * the closing needs to happen outside of the compilation itself. If the stream is not one of the
   * standard streams, i.e., System.out or System.err, you should likely implement yor own consumer.
   */
  class StreamConsumer extends ForwardingConsumer {

    private final Origin origin;
    private final OutputStream outputStream;
    private Charset encoding = StandardCharsets.UTF_8;

    /** Consumer that writes to {@param outputStream}. */
    public StreamConsumer(Origin origin, OutputStream outputStream) {
      this(origin, outputStream, null);
    }

    /** Consumer that forwards to {@param consumer} and also writes to {@param outputStream}. */
    public StreamConsumer(Origin origin, OutputStream outputStream, StringConsumer consumer) {
      super(consumer);
      this.origin = origin;
      this.outputStream = outputStream;
    }

    /** Set the encoding. Defaults to UTF8. */
    public void setEncoding(Charset encoding) {
      assert encoding != null;
      this.encoding = encoding;
    }

    @Override
    public void accept(String string, DiagnosticsHandler handler) {
      super.accept(string, handler);
      // Don't close this writer as it will close the underlying stream, which we specifically do
      // not want.
      BufferedWriter writer =
          new BufferedWriter(new OutputStreamWriter(outputStream, encoding.newEncoder()));
      try {
        writer.write(string);
        writer.flush();
      } catch (IOException e) {
        handler.error(new ExceptionDiagnostic(e, origin));
      }
    }
  }
}
