// Copyright 2010 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.testing.junit.runner.model;

import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.testing.junit.runner.util.XmlEscapers;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

/**
 * Writer for XML documents. We do not use third-party code, because all
 * java_test rules have the test runner in their run-time classpath.
 */
public class XmlWriter {
  // VisibleForTesting
  static final String EOL = System.getProperty("line.separator", "\n");

  private final Writer writer;
  private boolean started;
  private boolean inElement;
  private final List<String> elementStack = new ArrayList<>();

  /**
   * Creates an XML writer that writes to the given {@code OutputStream}.
   *
   * @param outputStream stream to write to
   */
  public XmlWriter(OutputStream outputStream) {
    this(new OutputStreamWriter(outputStream, UTF_8));
  }

  private XmlWriter(Writer writer) {
    this.writer = writer;
  }

  /**
   * Creates an XML writer for testing purposes. Note that if you decide to
   * serialize the {@code StringWriter} (to disk or network) encode it in {@code
   * UTF-8}.
   *
   * VisibleForTesting
   *
   * @param writer
   */
  public static XmlWriter createForTesting(StringWriter writer) {
    return new XmlWriter(writer);
  }

  /**
   * Starts the XML document.
   *
   * @throws IOException if the underlying writer throws an exception
   */
  public void startDocument() throws IOException {
    if (started) {
      throw new IllegalStateException("already started");
    }

    started = true;
    Writer out = writer;
    out.write("<?xml version='1.0' encoding='UTF-8'?>");
  }

  /**
   * Completes the XML document and closes the underlying writer.
   *
   * @throws IOException if the underlying writer throws an exception
   */
  public void close() throws IOException {
    while (!elementStack.isEmpty()) {
      endElement();
    }
    writer.append(EOL);
    writer.close();
  }

  private void closeElement() throws IOException {
    if (inElement) {
      writer.append('>');
      inElement = false;
    }
  }

  private String indentation() {
    int stackSize = elementStack.size();
    StringBuilder ident = new StringBuilder(2 * stackSize);
    for (int i = 0; i < stackSize; i++) {
      ident.append("  ");
    }
    return ident.toString();
  }

  /**
   * Starts an XML element. The element is left open until either
   * {@link #endElement()} or {@link #close()} are called. This method may be
   * called multiple times before calling {@link #endElement()}; the writer
   * keeps a stack of currently open elements.
   *
   * @param elementName name of the element (must be XML safe or escaped)
   * @throws IOException if the underlying writer throws an exception
   */
  public void startElement(String elementName) throws IOException {
    if (!started) {
      throw new IllegalStateException();
    }
    closeElement();
    inElement = true;
    writer.append(EOL + indentation() + "<" + elementName);
    elementStack.add(elementName);
  }

  /**
   * Ends the current XML element.
   *
   * @throws IOException if the underlying writer throws an exception
   */
  public void endElement() throws IOException {
    String elementName = elementStack.remove(elementStack.size() - 1);
    if (inElement) {
      writer.write(" />");
      inElement = false;
    } else {
      /*
       * We'd like to add a newline and indentation here, but that makes them part of the element
       * content, and that might be significant in test outputs, especially those that contain
       * actual and expected values.
       */
      writer.write("</");
      writer.write(elementName);
      writer.write('>');
    }
  }

  /**
   * Writes an attribute with the given integer value to the currently open XML
   * element.
   *
   * @param name attribute name
   * @param value attribute value
   * @throws IOException
   */
  public void writeAttribute(String name, int value) throws IOException {
    writeAttributeWithoutEscaping(name, String.valueOf(value));
  }

  /**
   * Writes an attribute with the given double value to the currently open XML
   * element.
   *
   * @param name attribute name
   * @param value attribute value (must be XML safe or escaped)
   * @throws IOException
   */
  public void writeAttribute(String name, double value) throws IOException {
    writeAttributeWithoutEscaping(name, String.valueOf(value));
  }

  /**
   * Writes an attribute to the currently open XML element.
   *
   * @param name attribute name (must be XML safe or escaped)
   * @param value attribute value (will be escaped by this method)
   * @throws IOException
   */
  public void writeAttribute(String name, String value) throws IOException {
    if (value != null) {
      value = XmlEscapers.xmlAttributeEscaper().escape(value);
    }
    writeAttributeWithoutEscaping(name, value);
  }

  private void writeAttributeWithoutEscaping(String name, String value) throws IOException {
    writer.write(" " + name + "='");
    if (value != null) {
      writer.write(value);
    }
    writer.write("'");
  }

  /**
   * Writes the given characters as the content of the element. Closes the
   * element if it is currently open.
   *
   * @param text String to append to the current content of the element
   * @throws IOException
   */
  public void writeCharacters(String text) throws IOException {
    closeElement();
    if (text == null || text.isEmpty()) {
      return;
    }
    writer.write(XmlEscapers.xmlContentEscaper().escape(text));
  }
}
