// 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.
#include "src/tools/singlejar/test_util.h"

#include <fcntl.h>
#include <stdarg.h>
#include <stdlib.h>
#include <sys/types.h>

#include <string>

#include "src/main/cpp/blaze_util.h"
#include "src/main/cpp/blaze_util_platform.h"
#include "src/main/cpp/util/file.h"
#include "src/main/cpp/util/file_platform.h"
#include "src/main/cpp/util/strings.h"

#include "gtest/gtest.h"

namespace singlejar_test_util {

bool AllocateFile(const string &name, size_t size) {
  int fd = open(name.c_str(), O_CREAT | O_RDWR | O_TRUNC, 0777);
  if (fd < 0) {
    perror(name.c_str());
    return false;
  }
  if (size) {
    if (ftruncate(fd, size) == 0) {
      return close(fd) == 0;
    } else {
      auto last_error = errno;
      close(fd);
      errno = last_error;
      return false;
    }
  } else {
    return close(fd) == 0;
  }
}

int RunCommand(const char *cmd, ...) {
  string args_string(cmd);
  va_list ap;
  va_start(ap, cmd);
  for (const char *arg = va_arg(ap, const char *); arg;
       arg = va_arg(ap, const char *)) {
    args_string += ' ';
    args_string += arg;
  }
  va_end(ap);
  fprintf(stderr, "Arguments: %s\n", args_string.c_str());
  return system(args_string.c_str());
}

// List zip file contents.
void LsZip(const char *zip_name) {
#if !defined(__APPLE__)
  RunCommand("unzip", "-v", zip_name, nullptr);
#endif
}

string OutputFilePath(const string &relpath) {
  const char *out_dir = getenv("TEST_TMPDIR");
  return blaze_util::JoinPath((nullptr == out_dir) ? "." : out_dir,
                              relpath.c_str());
}

int VerifyZip(const string &zip_path) {
  string verify_command;
  blaze_util::StringPrintf(&verify_command, "zip -Tv %s", zip_path.c_str());
  return system(verify_command.c_str());
}

string GetEntryContents(const string &zip_path, const string &entry_name) {
  string contents;
  string command;
  blaze_util::StringPrintf(&command, "unzip -p %s %s", zip_path.c_str(),
                           entry_name.c_str());
  FILE *fp = popen(command.c_str(), "r");
  if (!fp) {
    ADD_FAILURE() << "Command " << command << " failed.";
    return string("");
  }

  char buf[1024];
  while (fgets(buf, sizeof(buf), fp)) {
    contents.append(buf);
  }
  if (feof(fp) && !ferror(fp) && !pclose(fp)) {
    return contents;
  }
  ADD_FAILURE() << "Command " << command << " failed on close.";
  return string("");
}

string CreateTextFile(const string& relpath, const char *contents) {
  string out_path = OutputFilePath(relpath);
  blaze::MakeDirectories(blaze_util::Dirname(out_path), 0777);
  if (blaze_util::WriteFile(contents, out_path)) {
    return out_path;
  }
  ADD_FAILURE() << "Cannot write " << out_path;
  return string("");
}

}  // namespace singlejar_test_util
