// 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.
//
// This program creates a "runfiles tree" from a "runfiles manifest".
//
// The command line arguments are an input manifest INPUT and an output
// directory RUNFILES. First, the files in the RUNFILES directory are scanned
// and any extraneous ones are removed. Second, any missing files are created.
// Finally, a copy of the input manifest is written to RUNFILES/MANIFEST.
//
// The input manifest consists of lines, each containing a relative path within
// the runfiles, a space, and an optional absolute path.  If this second path
// is present, a symlink is created pointing to it; otherwise an empty file is
// created.
//
// Given the line
//   <workspace root>/output/path /real/path
// we will create directories
//   RUNFILES/<workspace root>
//   RUNFILES/<workspace root>/output
// a symlink
//   RUNFILES/<workspace root>/output/path -> /real/path
// and the output manifest will contain a line
//   <workspace root>/output/path /real/path
//
// If --use_metadata is supplied, every other line is treated as opaque
// metadata, and is ignored here.
//
// All output paths must be relative and generally (but not always) begin with
// <workspace root>. No output path may be equal to another.  No output path may
// be a path prefix of another.

#define _FILE_OFFSET_BITS 64

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>

#include <map>
#include <string>

// program_invocation_short_name is not portable.
static const char *argv0;

const char *input_filename;
const char *output_base_dir;

#define LOG() { \
  fprintf(stderr, "%s (args %s %s): ", \
          argv0, input_filename, output_base_dir); \
}

#define DIE(args...) { \
  LOG(); \
  fprintf(stderr, args); \
  fprintf(stderr, "\n"); \
  exit(1); \
}

#define PDIE(args...) { \
  int saved_errno = errno; \
  LOG(); \
  fprintf(stderr, args); \
  fprintf(stderr, ": %s [%d]\n", strerror(saved_errno), saved_errno); \
  exit(1); \
}

enum FileType {
  FILE_TYPE_REGULAR,
  FILE_TYPE_DIRECTORY,
  FILE_TYPE_SYMLINK
};

struct FileInfo {
  FileType type;
  std::string symlink_target;

  bool operator==(const FileInfo &other) const {
    return type == other.type && symlink_target == other.symlink_target;
  }

  bool operator!=(const FileInfo &other) const {
    return !(*this == other);
  }
};

typedef std::map<std::string, FileInfo> FileInfoMap;

class RunfilesCreator {
 public:
  explicit RunfilesCreator(const std::string &output_base)
      : output_base_(output_base),
        output_filename_("MANIFEST"),
        temp_filename_(output_filename_ + ".tmp") {
    SetupOutputBase();
    if (chdir(output_base_.c_str()) != 0) {
      PDIE("chdir '%s'", output_base_.c_str());
    }
  }

  void ReadManifest(const std::string &manifest_file, bool allow_relative,
                    bool use_metadata) {
    FILE *outfile = fopen(temp_filename_.c_str(), "w");
    if (!outfile) {
      PDIE("opening '%s/%s' for writing", output_base_.c_str(),
           temp_filename_.c_str());
    }
    FILE *infile = fopen(manifest_file.c_str(), "r");
    if (!infile) {
      PDIE("opening '%s' for reading", manifest_file.c_str());
    }

    // read input manifest
    int lineno = 0;
    char buf[3 * PATH_MAX];
    while (fgets(buf, sizeof buf, infile)) {
      // copy line to output manifest
      if (fputs(buf, outfile) == EOF) {
        PDIE("writing to '%s/%s'", output_base_.c_str(),
             temp_filename_.c_str());
      }

      // parse line
      ++lineno;
      // Skip metadata lines. They are used solely for
      // dependency checking.
      if (use_metadata && lineno % 2 == 0) continue;

      int n = strlen(buf)-1;
      if (!n || buf[n] != '\n') {
        DIE("missing terminator at line %d: '%s'\n", lineno, buf);
      }
      buf[n] = '\0';
      if (buf[0] ==  '/') {
        DIE("paths must not be absolute: line %d: '%s'\n", lineno, buf);
      }
      const char *s = strchr(buf, ' ');
      if (!s) {
        DIE("missing field delimiter at line %d: '%s'\n", lineno, buf);
      } else if (strchr(s+1, ' ')) {
        DIE("link or target filename contains space on line %d: '%s'\n",
            lineno, buf);
      }
      std::string link(buf, s-buf);
      const char *target = s+1;
      if (!allow_relative && target[0] != '\0' && target[0] != '/'
          && target[1] != ':') {  // Match Windows paths, e.g. C:\foo or C:/foo.
        DIE("expected absolute path at line %d: '%s'\n", lineno, buf);
      }

      FileInfo *info = &manifest_[link];
      if (target[0] == '\0') {
        // No target means an empty file.
        info->type = FILE_TYPE_REGULAR;
      } else {
        info->type = FILE_TYPE_SYMLINK;
        info->symlink_target = target;
      }

      FileInfo parent_info;
      parent_info.type = FILE_TYPE_DIRECTORY;

      while (true) {
        int k = link.rfind('/');
        if (k < 0) break;
        link.erase(k, std::string::npos);
        if (!manifest_.insert(std::make_pair(link, parent_info)).second) break;
      }
    }
    if (fclose(outfile) != 0) {
      PDIE("writing to '%s/%s'", output_base_.c_str(),
           temp_filename_.c_str());
    }
    fclose(infile);

    // Don't delete the temp manifest file.
    manifest_[temp_filename_].type = FILE_TYPE_REGULAR;
  }

  void CreateRunfiles() {
    if (unlink(output_filename_.c_str()) != 0 && errno != ENOENT) {
      PDIE("removing previous file at '%s/%s'", output_base_.c_str(),
           output_filename_.c_str());
    }

    ScanTreeAndPrune(".");
    CreateFiles();

    // rename output file into place
    if (rename(temp_filename_.c_str(), output_filename_.c_str()) != 0) {
      PDIE("renaming '%s/%s' to '%s/%s'",
           output_base_.c_str(), temp_filename_.c_str(),
           output_base_.c_str(), output_filename_.c_str());
    }
  }

 private:
  void SetupOutputBase() {
    struct stat st;
    if (stat(output_base_.c_str(), &st) != 0) {
      // Technically, this will cause problems if the user's umask contains
      // 0200, but we don't care. Anyone who does that deserves what's coming.
      if (mkdir(output_base_.c_str(), 0777) != 0) {
        PDIE("creating directory '%s'", output_base_.c_str());
      }
    } else {
      EnsureDirReadAndWritePerms(output_base_);
    }
  }

  void ScanTreeAndPrune(const std::string &path) {
    // A note on non-empty files:
    // We don't distinguish between empty and non-empty files. That is, if
    // there's a file that has contents, we don't truncate it here, even though
    // the manifest supports creation of empty files, only. Given that
    // .runfiles are *supposed* to be immutable, this shouldn't be a problem.
    EnsureDirReadAndWritePerms(path);

    struct dirent *entry;
    DIR *dh = opendir(path.c_str());
    if (!dh) {
      PDIE("opendir '%s'", path.c_str());
    }

    errno = 0;
    const std::string prefix = (path == "." ? "" : path + "/");
    while ((entry = readdir(dh)) != nullptr) {
      if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) continue;

      std::string entry_path = prefix + entry->d_name;
      FileInfo actual_info;
      actual_info.type = DentryToFileType(entry_path, entry);

      if (actual_info.type == FILE_TYPE_SYMLINK) {
        ReadLinkOrDie(entry_path, &actual_info.symlink_target);
      }

      FileInfoMap::iterator expected_it = manifest_.find(entry_path);
      if (expected_it == manifest_.end() ||
          expected_it->second != actual_info) {
#if !defined(__CYGWIN__)
        DelTree(entry_path, actual_info.type);
#else
        // On Windows, if deleting failed, lamely assume that
        // the link points to the right place.
        if (!DelTree(entry_path, actual_info.type)) {
          manifest_.erase(expected_it);
        }
#endif
      } else {
        manifest_.erase(expected_it);
        if (actual_info.type == FILE_TYPE_DIRECTORY) {
          ScanTreeAndPrune(entry_path);
        }
      }

      errno = 0;
    }
    if (errno != 0) {
      PDIE("reading directory '%s'", path.c_str());
    }
    closedir(dh);
  }

  void CreateFiles() {
    for (FileInfoMap::const_iterator it = manifest_.begin();
         it != manifest_.end(); ++it) {
      const std::string &path = it->first;
      switch (it->second.type) {
        case FILE_TYPE_DIRECTORY:
          if (mkdir(path.c_str(), 0777) != 0) {
            PDIE("mkdir '%s'", path.c_str());
          }
          break;
        case FILE_TYPE_REGULAR:
          {
            int fd = open(path.c_str(), O_CREAT|O_EXCL|O_WRONLY, 0555);
            if (fd < 0) {
              PDIE("creating empty file '%s'", path.c_str());
            }
            close(fd);
          }
          break;
        case FILE_TYPE_SYMLINK:
          {
            const std::string& target = it->second.symlink_target;
            if (symlink(target.c_str(), path.c_str()) != 0) {
              PDIE("symlinking '%s' -> '%s'", path.c_str(), target.c_str());
            }
          }
          break;
      }
    }
  }

  FileType DentryToFileType(const std::string &path, struct dirent *ent) {
#ifdef _DIRENT_HAVE_D_TYPE
    if (ent->d_type != DT_UNKNOWN) {
      if (ent->d_type == DT_DIR) {
        return FILE_TYPE_DIRECTORY;
      } else if (ent->d_type == DT_LNK) {
        return FILE_TYPE_SYMLINK;
      } else {
        return FILE_TYPE_REGULAR;
      }
    } else  // NOLINT (the brace is in the next line)
#endif
    {
      struct stat st;
      LStatOrDie(path, &st);
      if (S_ISDIR(st.st_mode)) {
        return FILE_TYPE_DIRECTORY;
      } else if (S_ISLNK(st.st_mode)) {
        return FILE_TYPE_SYMLINK;
      } else {
        return FILE_TYPE_REGULAR;
      }
    }
  }

  void LStatOrDie(const std::string &path, struct stat *st) {
    if (lstat(path.c_str(), st) != 0) {
      PDIE("lstating file '%s'", path.c_str());
    }
  }

  void StatOrDie(const std::string &path, struct stat *st) {
    if (stat(path.c_str(), st) != 0) {
      PDIE("stating file '%s'", path.c_str());
    }
  }

  void ReadLinkOrDie(const std::string &path, std::string *output) {
    char readlink_buffer[PATH_MAX];
    int sz = readlink(path.c_str(), readlink_buffer, sizeof(readlink_buffer));
    if (sz < 0) {
      PDIE("reading symlink '%s'", path.c_str());
    }
    // readlink returns a non-null terminated string.
    std::string(readlink_buffer, sz).swap(*output);
  }

  void EnsureDirReadAndWritePerms(const std::string &path) {
    const int kMode = 0700;
    struct stat st;
    LStatOrDie(path, &st);
    if ((st.st_mode & kMode) != kMode) {
      int new_mode = st.st_mode | kMode;
      if (chmod(path.c_str(), new_mode) != 0) {
        PDIE("chmod '%s'", path.c_str());
      }
    }
  }

  bool DelTree(const std::string &path, FileType file_type) {
    if (file_type != FILE_TYPE_DIRECTORY) {
      if (unlink(path.c_str()) != 0) {
#if !defined(__CYGWIN__)
        PDIE("unlinking '%s'", path.c_str());
#endif
        return false;
      }
      return true;
    }

    EnsureDirReadAndWritePerms(path);

    struct dirent *entry;
    DIR *dh = opendir(path.c_str());
    if (!dh) {
      PDIE("opendir '%s'", path.c_str());
    }
    errno = 0;
    while ((entry = readdir(dh)) != nullptr) {
      if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) continue;
      const std::string entry_path = path + '/' + entry->d_name;
      FileType entry_file_type = DentryToFileType(entry_path, entry);
      DelTree(entry_path, entry_file_type);
      errno = 0;
    }
    if (errno != 0) {
      PDIE("readdir '%s'", path.c_str());
    }
    closedir(dh);
    if (rmdir(path.c_str()) != 0) {
      PDIE("rmdir '%s'", path.c_str());
    }
    return true;
  }

 private:
  std::string output_base_;
  std::string output_filename_;
  std::string temp_filename_;

  FileInfoMap manifest_;
};

int main(int argc, char **argv) {
  argv0 = argv[0];

  argc--; argv++;
  bool allow_relative = false;
  bool use_metadata = false;

  while (argc >= 1) {
    if (strcmp(argv[0], "--allow_relative") == 0) {
      allow_relative = true;
      argc--; argv++;
    } else if (strcmp(argv[0], "--use_metadata") == 0) {
      use_metadata = true;
      argc--; argv++;
    } else {
      break;
    }
  }

  if (argc != 2) {
    fprintf(stderr, "usage: %s "
            "[--allow_relative] [--use_metadata] "
            "INPUT RUNFILES\n",
            argv0);
    return 1;
  }

  input_filename = argv[0];
  output_base_dir = argv[1];

  std::string manifest_file = input_filename;
  if (input_filename[0] != '/') {
    char cwd_buf[PATH_MAX];
    if (getcwd(cwd_buf, sizeof(cwd_buf)) == nullptr) {
      PDIE("getcwd failed");
    }
    manifest_file = std::string(cwd_buf) + '/' + manifest_file;
  }

  RunfilesCreator runfiles_creator(output_base_dir);
  runfiles_creator.ReadManifest(manifest_file, allow_relative, use_metadata);
  runfiles_creator.CreateRunfiles();

  return 0;
}
