// Copyright 2016 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.android;

import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.ide.common.internal.PngCruncher;
import com.android.ide.common.internal.PngException;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Ordering;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.devtools.build.android.AndroidResourceMerger.MergingException;
import com.google.devtools.build.android.AndroidResourceMergingAction.Options;
import com.google.devtools.build.android.junctions.JunctionCreator;
import com.google.devtools.build.android.junctions.NoopJunctionCreator;
import com.google.devtools.build.android.junctions.WindowsJunctionCreator;
import com.google.devtools.build.android.xml.Namespaces;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import javax.annotation.Nullable;
import javax.xml.namespace.QName;

/** Writer for UnwrittenMergedAndroidData. */
public class AndroidDataWriter implements AndroidDataWritingVisitor {

  private static final class CrunchTask implements Callable<Boolean> {
    private final Path destinationPath;
    private final Path source;
    private final PngCruncher cruncher;

    private CrunchTask(PngCruncher cruncher, Path destinationPath, Path source) {
      this.cruncher = cruncher;
      this.destinationPath = destinationPath;
      this.source = source;
    }

    @Override
    public Boolean call() throws Exception {
      try (JunctionCreator junc =
          System.getProperty("os.name").toLowerCase().startsWith("windows")
              ? new WindowsJunctionCreator(Files.createTempDirectory("pngcrunch"))
              : new NoopJunctionCreator()) {
        Files.createDirectories(destinationPath.getParent());
        cruncher.crunchPng(0, junc.create(source).toFile(), junc.create(destinationPath).toFile());
      } catch (PngException e) {
        throw MergingException.wrapException(e);
      }
      return Boolean.TRUE;
    }
  }

  private static final class CopyTask implements Callable<Boolean> {

    private final Path sourcePath;

    private final Path destinationPath;

    private CopyTask(Path sourcePath, Path destinationPath) {
      this.sourcePath = sourcePath;
      this.destinationPath = destinationPath;
    }

    @Override
    public Boolean call() throws Exception {
      Files.createDirectories(destinationPath.getParent());
      Files.copy(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);
      return Boolean.TRUE;
    }
  }

  public static final char[] PRELUDE =
      "<?xml version=\"1.0\" encoding='utf-8' standalone='no'?>\n".toCharArray();
  private static final char[] START_RESOURCES_TAG = "<resources".toCharArray();
  public static final char[] END_RESOURCES = "</resources>".toCharArray();
  private static final char[] LINE_END = "\n".toCharArray();
  static final PngCruncher NOOP_CRUNCHER =
      new PngCruncher() {
        @Override
        public int start() {
          return 0;
        }

        @Override
        public void end(int key) throws InterruptedException {}

        @Override
        public void crunchPng(int key, @NonNull File source, @NonNull File destination)
            throws PngException {
          try {
            Files.createDirectories(destination.toPath().getParent());
            Files.copy(source.toPath(), destination.toPath());
          } catch (IOException e) {
            throw new PngException(e);
          }
        }
      };

  /**
   * The merged {@link Options#resourcesOutput} is only used for validation and not for running
   * (unlike the final APK), so the image files do not need to be the true image files. We only need
   * the filenames to be the same.
   *
   * <p>Thus, we only create empty files for PNGs (convenient with a custom PngCruncher object).
   * This does miss out on other image files like .webp.
   */
  static final PngCruncher STUB_CRUNCHER =
      new PngCruncher() {

        @Override
        public void crunchPng(int key, File from, File to) throws PngException {
          try {
            to.createNewFile();
            if (!to.setLastModified(System.currentTimeMillis())) {
              throw new PngException("Could not set milliseconds");
            }
          } catch (IOException e) {
            throw new PngException(e);
          }
        }

        @Override
        public int start() {
          return 0;
        }

        @Override
        public void end(int key) {}
      };

  private final Path destination;

  private final Map<String, ResourceValuesDefinitions> valueTags = new HashMap<>();
  private final Path resourceDirectory;
  private final Path assetDirectory;
  private final PngCruncher cruncher;
  private final List<ListenableFuture<Boolean>> writeTasks = new ArrayList<>();
  private final ListeningExecutorService executorService;

  private AndroidDataWriter(
      Path destination,
      Path resourceDirectory,
      Path assetsDirectory,
      PngCruncher cruncher,
      ListeningExecutorService executorService) {
    this.destination = destination;
    this.resourceDirectory = resourceDirectory;
    this.assetDirectory = assetsDirectory;
    this.cruncher = cruncher;
    this.executorService = executorService;
  }

  /**
   * Creates a new, naive writer for testing.
   *
   * <p>This writer has "assets" and a "res" directory from the destination directory, as well as a
   * noop png cruncher and a {@link ExecutorService} of 1 thread.
   *
   * @param destination The base directory to derive all paths.
   * @return A new {@link AndroidDataWriter}.
   */
  @VisibleForTesting
  static AndroidDataWriter createWithDefaults(Path destination) {
    return createWith(
        destination,
        destination.resolve("res"),
        destination.resolve("assets"),
        NOOP_CRUNCHER,
        MoreExecutors.newDirectExecutorService());
  }

  /**
   * Creates a new writer.
   *
   * @param manifestDirectory The base directory for the AndroidManifest.
   * @param resourceDirectory The directory to copy resources into.
   * @param assetsDirectory The directory to copy assets into.
   * @param cruncher The cruncher for png files. If the cruncher is null, it will be replaced with a
   *     noop cruncher.
   * @param executorService An execution service for multi-threaded writing.
   * @return A new {@link AndroidDataWriter}.
   */
  public static AndroidDataWriter createWith(
      Path manifestDirectory,
      Path resourceDirectory,
      Path assetsDirectory,
      @Nullable PngCruncher cruncher,
      ListeningExecutorService executorService) {
    return new AndroidDataWriter(
        manifestDirectory,
        resourceDirectory,
        assetsDirectory,
        cruncher == null ? NOOP_CRUNCHER : cruncher,
        executorService);
  }

  @Override
  public Path copyManifest(Path sourceManifest) throws IOException {
    // aapt won't read any manifest that is not named AndroidManifest.xml,
    // so we hard code it here.
    Path destinationManifest = destination.resolve("AndroidManifest.xml");
    copy(sourceManifest, destinationManifest);
    return destinationManifest;
  }

  public Path assetDirectory() {
    return assetDirectory;
  }

  public Path resourceDirectory() {
    return resourceDirectory;
  }

  @Override
  public void copyAsset(Path source, String relativeDestinationPath) throws IOException {
    copy(source, assetDirectory.resolve(relativeDestinationPath));
  }

  @Override
  public void copyResource(final Path source, final String relativeDestinationPath)
      throws MergingException {
    final Path destinationPath = resourceDirectory.resolve(relativeDestinationPath);
    if (!source.getParent().getFileName().toString().startsWith(SdkConstants.FD_RES_RAW)
        && source.getFileName().toString().endsWith(SdkConstants.DOT_PNG)) {
      writeTasks.add(executorService.submit(new CrunchTask(cruncher, destinationPath, source)));
    } else {
      copy(source, destinationPath);
    }
  }

  private void copy(final Path sourcePath, final Path destinationPath) {
    writeTasks.add(executorService.submit(new CopyTask(sourcePath, destinationPath)));
  }

  /** Finalizes all operations and flushes the buffers. */
  @Override
  public void flush() throws IOException {
    for (Map.Entry<String, ResourceValuesDefinitions> entry : valueTags.entrySet()) {
      writeTasks.add(
          executorService.submit(
              entry.getValue().createWritingTask(resourceDirectory().resolve(entry.getKey()))));
    }

    FailedFutureAggregator.forIOExceptionsWithMessage("Failures during writing.")
        .aggregateAndMaybeThrow(writeTasks);

    writeTasks.clear();
  }

  @Override
  public ValueResourceDefinitionMetadata define(FullyQualifiedName fqn) {
    String valuesPath = fqn.valuesPath();
    if (!valueTags.containsKey(valuesPath)) {
      valueTags.put(valuesPath, new ResourceValuesDefinitions());
    }
    return valueTags.get(valuesPath).resource(fqn);
  }

  @Override
  public void defineAttribute(FullyQualifiedName fqn, String name, String value) {
    String valuesPath = fqn.valuesPath();
    if (!valueTags.containsKey(valuesPath)) {
      valueTags.put(valuesPath, new ResourceValuesDefinitions());
    }
    valueTags.get(valuesPath).addAttribute(name, value);
  }

  @Override
  public void defineNamespacesFor(FullyQualifiedName fqn, Namespaces namespaces) {
    String valuesPath = fqn.valuesPath();
    if (!valueTags.containsKey(valuesPath)) {
      valueTags.put(valuesPath, new ResourceValuesDefinitions());
    }
    valueTags.get(valuesPath).addAllNamespaces(namespaces);
  }

  /** A container for the {@linkplain Segment}s of a values.xml file. */
  private static class ResourceValuesDefinitions {
    private static final class WritingTask implements Callable<Boolean> {

      private final Path valuesPath;

      private final Multimap<FullyQualifiedName, Segment> segments;
      private final Set<FullyQualifiedName> adopted;
      private final Namespaces namespaces;
      private final Map<String, String> attributes;

      private WritingTask(
          Path valuesPath,
          Namespaces namespaces,
          Map<String, String> attributes,
          Set<FullyQualifiedName> adopted,
          Multimap<FullyQualifiedName, Segment> segments) {
        this.valuesPath = valuesPath;
        this.namespaces = namespaces;
        this.attributes = attributes;
        this.adopted = adopted;
        this.segments = segments;
      }

      @Override
      public Boolean call() throws Exception {
        Files.createDirectories(valuesPath.getParent());
        try (BufferedWriter writer =
            Files.newBufferedWriter(
                valuesPath,
                StandardCharsets.UTF_8,
                StandardOpenOption.CREATE_NEW,
                StandardOpenOption.WRITE)) {
          writer.write(PRELUDE);
          writer.write(START_RESOURCES_TAG);
          for (Map.Entry<String, String> prefixToUri : namespaces) {
            writer.write(" xmlns:");
            writer.write(prefixToUri.getKey());
            writer.write("=\"");
            writer.write(prefixToUri.getValue());
            writer.write("\"");
          }
          for (Map.Entry<String, String> attribute : attributes.entrySet()) {
            writer.write(" ");
            writer.write(attribute.getKey());
            writer.write("=\"");
            writer.write(attribute.getValue());
            writer.write("\"");
          }
          writer.write(">");
          writer.write(LINE_END);
          Path previousSource = null;
          for (FullyQualifiedName key : Ordering.natural().immutableSortedCopy(segments.keySet())) {
            if (!adopted.contains(key)) {
              for (Segment segment : segments.get(key)) {
                previousSource = segment.write(previousSource, writer);
              }
            }
          }
          writer.write(END_RESOURCES);
        }
        return Boolean.TRUE;
      }
    }

    final Multimap<FullyQualifiedName, Segment> segments = ArrayListMultimap.create();
    final Set<FullyQualifiedName> adopted = new HashSet<>();
    Namespaces namespaces = Namespaces.empty();
    final Map<String, String> attributes = Maps.newHashMap();

    private ValueResourceDefinitionMetadata resource(final FullyQualifiedName fqn) {
      return new StringValueResourceDefinitionMetadata(segments, adopted, fqn);
    }

    public void addAttribute(String name, String value) {
      this.attributes.put(name, value);
    }

    public void addAllNamespaces(Namespaces namespaces) {
      this.namespaces = namespaces.union(this.namespaces);
    }

    /** Generates a {@link Callable} that will write the {@link Segment} to the provided path. */
    public Callable<Boolean> createWritingTask(final Path valuesPath) {
      return new WritingTask(valuesPath, namespaces, attributes, adopted, segments);
    }
  }

  /** Utility function to provide xml namespaced name if a prefix is defined. */
  private static String maybePrefixName(@Nullable String prefix, String name) {
    if (prefix == null) {
      return name;
    }
    return prefix + ":" + name;
  }

  /** Intermediate class that associates a {@link Path} source with an xml definition. */
  private static class StringValueResourceDefinitionMetadata
      implements ValueResourceDefinitionMetadata {

    private final Multimap<FullyQualifiedName, Segment> segments;
    private final Set<FullyQualifiedName> adopted;
    private final FullyQualifiedName segmentsKey;

    public StringValueResourceDefinitionMetadata(
        Multimap<FullyQualifiedName, Segment> segments,
        Set<FullyQualifiedName> adopted,
        FullyQualifiedName fqn) {
      this.segments = segments;
      this.adopted = adopted;
      this.segmentsKey = fqn;
    }

    @Override
    public ValuesResourceDefinition derivedFrom(final DataSource source) {
      final SegmentMapper mapper =
          SegmentMapper.create(segments, adopted, segmentsKey, source.getPath());
      return new StringValuesResourceDefinition(mapper);
    }
  }

  /** Intermediate class that builds a string attribute for a {@link StartTag} */
  private static final class StringAttribute implements Attribute {

    private final String name;
    private final StringStartTag owner;
    private final boolean optional;

    public StringAttribute(StringStartTag owner, String name, boolean optional) {
      this.owner = owner;
      this.name = name;
      this.optional = optional;
    }

    @Override
    public StartTag setTo(FullyQualifiedName fqn) {
      return setTo(fqn.name());
    }

    @Override
    public StartTag setTo(String value) {
      if (!optional || value != null) {
        owner.attributes.add(" " + name + "=\"" + value + "\"");
      }
      return owner;
    }

    @Override
    public ValueJoiner setFrom(final Iterable<String> values) {
      return new ValueJoiner() {
        @Override
        public StartTag joinedBy(String separator) {
          Iterator<String> valuesIterator = values.iterator();
          if (!optional || valuesIterator.hasNext()) {
            setTo(Joiner.on(separator).join(valuesIterator));
          }
          return owner;
        }
      };
    }
  }

  /** Intermediate class that collects information for writing an xml start tag string. */
  private static final class StringStartTag implements StartTag {
    private final StringValuesResourceDefinition writer;
    private final String tagName;
    private final List<String> attributes = new ArrayList<>();

    public StringStartTag(StringValuesResourceDefinition writer, String tagName) {
      this.writer = writer;
      this.tagName = tagName;
    }

    @Override
    public Attribute attribute(String prefix, String name) {
      return createAttribute(prefix, name, false);
    }

    @Override
    public StringValuesResourceDefinition closeTag() {
      // Make sure we close this later.
      writer.tagStack.push(tagName);
      writer.mapper.add("<" + tagName + Joiner.on("").join(attributes) + ">");
      return writer;
    }

    @Override
    public Attribute attribute(String name) {
      return attribute(null, name);
    }

    private Attribute createAttribute(String prefix, String name, boolean optional) {
      return new StringAttribute(this, maybePrefixName(prefix, name), optional);
    }

    @Override
    public Optional optional() {
      return new Optional() {
        @Override
        public Attribute attribute(String prefix, String name) {
          return createAttribute(prefix, name, true);
        }

        @Override
        public Attribute attribute(String name) {
          return createAttribute(null, name, true);
        }
      };
    }

    @Override
    public ValuesResourceDefinition closeUnaryTag() {
      writer.mapper.add("\n<" + tagName + Joiner.on("").join(attributes) + "/>");
      return writer;
    }

    @Override
    public StartTag named(FullyQualifiedName key) {
      return named(key.name());
    }

    @Override
    public StartTag named(String name) {
      return createAttribute(null, "name", false).setTo(name);
    }

    @Override
    public StartTag addAttributesFrom(Iterable<Map.Entry<String, String>> entries) {
      StartTag tag = this;
      for (Map.Entry<String, String> entry : entries) {
        tag = tag.attribute(entry.getKey()).setTo(entry.getValue());
      }
      return tag;
    }
  }

  /** Intermediate class that provides methods to generate string xml definitions. */
  static class StringValuesResourceDefinition implements ValuesResourceDefinition {
    private final SegmentMapper mapper;
    private final Deque<String> tagStack = new ArrayDeque<>();

    public StringValuesResourceDefinition(SegmentMapper mapper) {
      this.mapper = mapper;
    }

    @Override
    public StartTag startTag(String prefix, String localName) {
      final String tagName = maybePrefixName(prefix, localName);
      return new StringStartTag(this, tagName);
    }

    @Override
    public StartTag startTag(String localName) {
      return startTag(null, localName);
    }

    @Override
    public StartTag startTag(QName name) {
      return startTag(name.getPrefix().isEmpty() ? null : name.getPrefix(), name.getLocalPart());
    }

    @Override
    public ValuesResourceDefinition adopt(FullyQualifiedName fqn) {
      mapper.adopt(fqn);
      return this;
    }

    @Override
    public ValuesResourceDefinition addCharactersOf(String characters) {
      mapper.add(characters);
      return this;
    }

    @Override
    public ValuesResourceDefinition endTag() {
      Preconditions.checkArgument(
          !tagStack.isEmpty(), "Unable to endTag, as no tag has been started.");
      mapper.add("</" + tagStack.pop() + ">");
      return this;
    }

    @Override
    public void save() {
      Preconditions.checkArgument(tagStack.isEmpty(), "Unfinished tags %s", tagStack);
      mapper.add("\n"); // Safe to add a line break to separate from other definitions.
      mapper.finish();
    }

    @Override
    public StartTag startItemTag() {
      return startTag("item");
    }
  }

  /** Maps {@link Segment}s to a {@link Multimap} via a {@link FullyQualifiedName} key. */
  private static class SegmentMapper {
    private List<String> currentLines = new ArrayList<>();

    private final Multimap<FullyQualifiedName, Segment> segmentStore;
    final FullyQualifiedName segmentKey;

    private final Set<FullyQualifiedName> adopted;

    private SegmentMapper(
        Set<FullyQualifiedName> adopted,
        Multimap<FullyQualifiedName, Segment> segmentStore,
        FullyQualifiedName segmentKey) {
      this.adopted = adopted;
      this.segmentStore = segmentStore;
      this.segmentKey = segmentKey;
    }

    static SegmentMapper create(
        Multimap<FullyQualifiedName, Segment> segmentStore,
        Set<FullyQualifiedName> adopted,
        FullyQualifiedName segmentKey,
        Path source) {
      Preconditions.checkNotNull(source);
      segmentStore.put(segmentKey, new SourceSegment(source));
      return new SegmentMapper(adopted, segmentStore, segmentKey);
    }

    /** Adds a string to the current {@link StringsSegment}. */
    SegmentMapper add(String line) {
      currentLines.add(line);
      return this;
    }

    /** Closes current {@link StringsSegment} and adds a {@link ReferenceSegment} to the store. */
    SegmentMapper adopt(FullyQualifiedName adoptedKey) {
      segmentStore.put(segmentKey, new StringsSegment(currentLines));
      adopted.add(adoptedKey);
      segmentStore.put(segmentKey, new ReferenceSegment(adoptedKey, segmentStore));
      currentLines = new ArrayList<>();
      return this;
    }

    /** Ends the mapping for the current key. */
    void finish() {
      segmentStore.put(segmentKey, new StringsSegment(currentLines));
    }
  }

  /** Base interface for writing information to a {@link Writer}. */
  private static interface Segment {
    /**
     * Writes the segment contents to a Writer
     *
     * @param previousSource The source Path of the last Segment to be written. This can be used to
     *     omit source annotations from the Writer is the last source matches the current one.
     * @param writer The writer of the segments.
     * @return The source Path of this segment for the next segment.
     * @throws IOException thrown by the writer.
     */
    Path write(Path previousSource, @Nullable Writer writer) throws IOException;
  }

  /** Represents a reference to another list of {@link Segment}s from the {@link Multimap}. */
  private static class ReferenceSegment implements Segment {
    private final FullyQualifiedName fqn;
    private final Multimap<FullyQualifiedName, Segment> segmentsByName;

    public ReferenceSegment(
        FullyQualifiedName fqn, Multimap<FullyQualifiedName, Segment> segmentsByName) {
      this.fqn = fqn;
      this.segmentsByName = segmentsByName;
    }

    @Override
    public Path write(Path previousSource, Writer writer) throws IOException {
      Path source = previousSource;
      Preconditions.checkArgument(
          segmentsByName.containsKey(fqn),
          "%s has no segment in %s",
          fqn.toPrettyString(),
          segmentsByName.keySet());
      for (Segment s : segmentsByName.get(fqn)) {
        // not recording the source
        source = s.write(source, writer);
      }
      return source;
    }
  }

  /** A simple container for a list of strings to be written. */
  private static class StringsSegment implements Segment {
    private final List<String> lines;

    public StringsSegment(List<String> lines) {
      this.lines = lines;
    }

    @Override
    public Path write(Path previousSource, Writer writer) throws IOException {
      for (String line : lines) {
        writer.write(line);
      }
      return previousSource;
    }
  }

  /** Represents a resource source annotation to be written as xml. */
  private static class SourceSegment implements Segment {

    private final Path source;

    SourceSegment(Path source) {
      this.source = source;
    }

    @Override
    public Path write(Path previousSource, Writer writer) throws IOException {
      // If sources are equal don't write a new source annotation.
      if (source.equals(previousSource)) {
        return previousSource;
      }
      writer.write(String.format("<!-- %s -->", source));
      writer.write(LINE_END);
      writer.write("<eat-comment/>");
      writer.write(LINE_END);
      return source;
    }
  }
}
