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

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Representation of a set of file dependencies for a given output file. There
 * are generally one input dependency and a bunch of include dependencies. The
 * files are stored as {@code Path}s and may be relative or absolute.
 * <p>
 * The serialized format read and written is equivalent and compatible with the
 * ".d" file produced by the -MM for a given out (.o) file.
 * <p>
 * The file format looks like:
 *
 * <pre>
 * {outfile}:  \
 *  {infile} \
 *   {include} \
 *   ... \
 *   {include}
 * </pre>
 *
 * @see "http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Preprocessor-Options.html#Preprocessor-Options"
 */
public final class DependencySet {

  /**
   * The set of dependent files that this DependencySet embodies. They are all
   * Path with the same FileSystem  A tree set is used to ensure that we
   * write them out in a consistent order.
   */
  private final Collection<Path> dependencies = new ArrayList<>();

  private final Path root;
  private String outputFileName;

  /**
   * Get output file name for which dependencies are included in this DependencySet.
   */
  public String getOutputFileName() {
    return outputFileName;
  }

  public void setOutputFileName(String outputFileName) {
    this.outputFileName = outputFileName;
  }

  /**
   * Constructs a new empty DependencySet instance.
   */
  public DependencySet(Path root) {
    this.root = root;
  }

  /**
   * Gets an unmodifiable view of the set of dependencies in {@link Path} form
   * from this DependencySet instance.
   */
  public Collection<Path> getDependencies() {
    return Collections.unmodifiableCollection(dependencies);
  }

  /**
   * Adds a given collection of dependencies in Path form to this DependencySet
   * instance. Paths are converted to root-relative
   */
  @VisibleForTesting // only called from DependencySetTest
  public void addDependencies(Collection<Path> deps) {
    for (Path d : deps) {
      Preconditions.checkArgument(d.startsWith(root));
      dependencies.add(d);
    }
  }

  /**
   * Adds a given dependency to this DependencySet instance.
   */
  private void addDependency(String dep) {
    dep = translatePath(dep);
    Path depPath = root.getRelative(dep);
    dependencies.add(depPath);
  }

  private String translatePath(String path) {
    if (OS.getCurrent() != OS.WINDOWS) {
      return path;
    }
    return WindowsPath.translateWindowsPath(path);
  }

  /**
   * Reads a dotd file into this DependencySet instance.
   */
  public DependencySet read(Path dotdFile) throws IOException {
    byte[] content = FileSystemUtils.readContent(dotdFile);
    try {
      return process(content);
    } catch (IOException e) {
      throw new IOException("Error processing " + dotdFile + ": " + e.getMessage());
    }
  }

  /**
   * Parses a .d file.
   *
   * <p>Performance-critical! In large C++ builds there are lots of .d files to read, and some of
   * them reach into hundreds of kilobytes.
   */
  public DependencySet process(byte[] content) throws IOException {
    final int n = content.length;
    if (n > 0 && content[n - 1] != '\n') {
      throw new IOException("File does not end in a newline");
      // From now on, we can safely peek ahead one character when not at a newline.
    }
    // Our write position in content[]; we use the prefix as working space to build strings.
    int w = 0;
    // Have we seen a leading "mumble.o:" on this line yet?  If not, we ignore
    // any dependencies we parse.  This is bug-for-bug compatibility with our
    // MSVC wrapper, which generates invalid .d files :(
    boolean sawTarget = false;
    for (int r = 0; r < n; ) {
      final byte c = content[r++];
      switch (c) {

        case ' ':
          // If we haven't yet seen the colon delimiting the target name,
          // keep scanning.  We do this to cope with "foo.o : \" which is
          // valid Makefile syntax produced by the cuda compiler.
          if (sawTarget && w > 0) {
            addDependency(new String(content, 0, w, StandardCharsets.UTF_8));
            w = 0;
          }
          continue;

        case '\r':
          // Ignore, should be followed by a \n.
          continue;

        case '\n':
          // This closes a filename.
          // (Arguably if !sawTarget && w > 0 we should report an error,
          // as that suggests the .d file is malformed.)
          if (sawTarget && w > 0) {
            addDependency(new String(content, 0, w, StandardCharsets.UTF_8));
          }
          w = 0;
          sawTarget = false;  // reset for new line
          continue;

        case ':':
          // Normally this indicates the target name, but it might be part of a
          // filename on Windows.  Peek ahead at the next character.
          switch (content[r]) {
            case ' ':
            case '\n':
            case '\r':
              if (w > 0) {
                outputFileName = new String(content, 0, w, StandardCharsets.UTF_8);
                w = 0;
                sawTarget = true;
              }
              continue;
            default:
              content[w++] = c;  // copy a colon to filename
              continue;
          }

        case '\\':
          // Peek ahead at the next character.
          switch (content[r]) {
            // Backslashes are taken literally except when followed by whitespace.
            // See the Windows tests for some of the nonsense we have to tolerate.
            case ' ':
              content[w++] = ' ';  // copy a space to the filename
              ++r;  // skip over the space
              continue;
            case '\n':
              ++r;  // skip over the newline
              continue;
            case '\r':
              // One backslash can escape \r\n, so peek one more character.
              if (content[++r] == '\n') {
                ++r;
              }
              continue;
            default:
              content[w++] = c;  // copy a backlash to the filename
              continue;
          }

        default:
          content[w++] = c;

      }
    }
    return this;
  }

  /**
   * Writes this DependencySet object for a specified output file under the root
   * dir, and with a given suffix.
   */
  public void write(Path outFile, String suffix) throws IOException {
    Path dotdFile =
        outFile.getRelative(FileSystemUtils.replaceExtension(outFile.asFragment(), suffix));

    try (PrintStream out = new PrintStream(dotdFile.getOutputStream())) {
      out.print(outFile.relativeTo(root) + ": ");
      for (Path d : dependencies) {
        out.print(" \\\n  " + d.getPathString());  // should already be root relative
      }
      out.println();
    }
  }

  @Override
  public boolean equals(Object other) {
    return other instanceof DependencySet
        && ((DependencySet) other).dependencies.equals(dependencies);
  }

  @Override
  public int hashCode() {
    return dependencies.hashCode();
  }

  private static final class WindowsPath {
    private static final AtomicReference<String> UNIX_ROOT = new AtomicReference<>(null);

    private static String translateWindowsPath(String path) {
      int n = path.length();
      if (n == 0 || path.charAt(0) != '/') {
        return path;
      }
      if (n >= 2 && isAsciiLetter(path.charAt(1)) && (n == 2 || path.charAt(2) == '/')) {
        StringBuilder sb = new StringBuilder(path.length());
        sb.append(Character.toUpperCase(path.charAt(1)));
        sb.append(":/");
        sb.append(path, 2, path.length());
        return sb.toString();
      } else {
        String unixRoot = getUnixRoot();
        return unixRoot + path;
      }
    }

    private static boolean isAsciiLetter(char c) {
      return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
    }

    private static String getUnixRoot() {
      String value = UNIX_ROOT.get();
      if (value == null) {
        String jvmFlag = "bazel.windows_unix_root";
        value = determineUnixRoot(jvmFlag);
        if (value == null) {
          throw new IllegalStateException(
              String.format(
                  "\"%1$s\" JVM flag is not set. Use the --host_jvm_args flag. "
                      + "For example: "
                      + "\"--host_jvm_args=-D%1$s=c:/tools/msys64\".",
                  jvmFlag));
        }
        value = value.replace('\\', '/');
        if (value.length() > 3 && value.endsWith("/")) {
          value = value.substring(0, value.length() - 1);
        }
        UNIX_ROOT.set(value);
      }
      return value;
    }

    private static String determineUnixRoot(String jvmArgName) {
      // Get the path from a JVM flag, if specified.
      String path = System.getProperty(jvmArgName);
      if (path == null) {
        return null;
      }
      path = path.trim();
      if (path.isEmpty()) {
        return null;
      }
      return path;
    }
  }
}
