// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "command_line_options.h"

#include <stdlib.h>
#include <unistd.h>

#include <filesystem>
#include <fstream>

#include "gtest/gtest.h"

namespace fidlcat {

class CommandLineOptionsTest : public ::testing::Test {
 protected:
  void SetUp() override {
    const char* tmpl = "tmp.XXXXXX";
    dir_.reset(new char[strlen(tmpl) + 1]);
    strcpy(dir_.get(), tmpl);
    mkdtemp(dir_.get());
  }

  void TearDown() override {
    for (auto& file : files_) {
      std::string full_filename = std::string(dir_.get()) +
                                  std::filesystem::path::preferred_separator +
                                  file;
      remove(full_filename.c_str());
    }
    remove(dir_.get());
  }

  std::unique_ptr<char[]> dir_;
  std::vector<std::string> files_;
};

// Test to ensure @argfile support works.
TEST_F(CommandLineOptionsTest, ArgfileTest) {
  std::ofstream os;
  std::string dir = std::string(dir_.get());
  std::string argfilename = "out.txt";
  std::string filename =
      dir + std::filesystem::path::preferred_separator + argfilename;
  files_ = {"foo.fidl.json", "bar.fidl.json"};

  // Write some content to each file, so that we have something to read to see
  // if the fidl paths were returned correctly.
  for (auto& file : files_) {
    std::ofstream fout;
    fout.open(dir + std::filesystem::path::preferred_separator + file,
              std::ofstream::out | std::ofstream::app);
    fout << file;
    fout.close();
  }

  // Write the filenames to the argfile.
  os.open(filename, std::ofstream::out | std::ofstream::app);
  for (auto& file : files_) {
    os << file << "\n";
  }
  os.close();

  // Parse the command line.
  std::string param = "@" + filename;
  const char* argv[] = {"fakebinary", "--fidl-ir-path", param.c_str()};
  int argc = sizeof(argv) / sizeof(argv[0]);
  CommandLineOptions options;
  std::vector<std::string> params;
  auto status = ParseCommandLine(argc, argv, &options, &params);
  ASSERT_TRUE(status.ok());
  ASSERT_EQ(0U, params.size())
      << "Expected 0 params, got (at least) " << params[0];

  // Expand the FIDL paths.
  std::vector<std::unique_ptr<std::istream>> paths;
  std::vector<std::string> bad_paths;
  ExpandFidlPathsFromOptions(options.fidl_ir_paths, paths, bad_paths);

  ASSERT_EQ(files_.size(), paths.size());

  for (size_t i = 0; i < paths.size(); i++) {
    std::string file_contents{std::istreambuf_iterator<char>(*paths[i]), {}};
    ASSERT_TRUE(paths[i]->good());
    ASSERT_EQ(files_[i], file_contents);
  }
  ASSERT_EQ(0U, bad_paths.size());

  // files_ also acts as the list of names files to delete.
  files_.push_back(argfilename);
}

// Test to ensure that non-existent files are reported accordingly.
TEST_F(CommandLineOptionsTest, BadOptionsTest) {
  // Parse the command line.
  const char* argv[] = {"fakebinary", "--fidl-ir-path", "blah.fidl.json",
                        "--fidl-ir-path", "@all_files.txt"};
  int argc = sizeof(argv) / sizeof(argv[0]);
  CommandLineOptions options;
  std::vector<std::string> params;
  auto status = ParseCommandLine(argc, argv, &options, &params);
  ASSERT_TRUE(status.ok());
  ASSERT_EQ(0U, params.size())
      << "Expected 0 params, got (at least) " << params[0];

  std::vector<std::unique_ptr<std::istream>> paths;
  std::vector<std::string> bad_paths;
  ExpandFidlPathsFromOptions(options.fidl_ir_paths, paths, bad_paths);

  ASSERT_EQ(2U, bad_paths.size());
  ASSERT_EQ(0U, paths.size());
}

// Test to ensure that ParseCommandLine works.
TEST_F(CommandLineOptionsTest, SimpleParseCommandLineTest) {
  std::string fidl_ir_path = "blah.fidl.json";
  std::string symbol_path = "path/to/debug/symbols";
  std::string remote_pid = "3141";
  std::string connect = "localhost:8080";
  const char* argv[] = {"fakebinary",
                        "--fidl-ir-path",
                        fidl_ir_path.c_str(),
                        "-s",
                        symbol_path.c_str(),
                        "--connect",
                        connect.c_str(),
                        "--remote-pid",
                        remote_pid.c_str(),
                        "leftover",
                        "args"};
  int argc = sizeof(argv) / sizeof(argv[0]);
  CommandLineOptions options;
  std::vector<std::string> params;
  auto status = ParseCommandLine(argc, argv, &options, &params);
  ASSERT_TRUE(status.ok());
  ASSERT_EQ(2U, params.size())
      << "Expected 0 params, got (at least) " << params[0];
  ASSERT_EQ(connect, *options.connect);
  ASSERT_EQ(remote_pid, *options.remote_pid);
  ASSERT_EQ(symbol_path, options.symbol_paths[0]);
  ASSERT_EQ(fidl_ir_path, options.fidl_ir_paths[0]);
  ASSERT_TRUE(std::find(params.begin(), params.end(), "leftover") !=
              params.end());
  ASSERT_TRUE(std::find(params.begin(), params.end(), "args") != params.end());
}

}  // namespace fidlcat
