/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * 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.
 */

#ifndef ART_COMPILER_UTILS_ASSEMBLER_TEST_BASE_H_
#define ART_COMPILER_UTILS_ASSEMBLER_TEST_BASE_H_

#include <sys/stat.h>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <iterator>

#include "android-base/strings.h"

#include "base/utils.h"
#include "common_runtime_test.h"  // For ScratchFile
#include "exec_utils.h"

namespace art {

// If you want to take a look at the differences between the ART assembler and GCC, set this flag
// to true. The disassembled files will then remain in the tmp directory.
static constexpr bool kKeepDisassembledFiles = false;

// Use a glocal static variable to keep the same name for all test data. Else we'll just spam the
// temp directory.
static std::string tmpnam_;  // NOLINT [runtime/string] [4]

// We put this into a class as gtests are self-contained, so this helper needs to be in an h-file.
class AssemblerTestInfrastructure {
 public:
  AssemblerTestInfrastructure(std::string architecture,
                              std::string as,
                              std::string as_params,
                              std::string objdump,
                              std::string objdump_params,
                              std::string disasm,
                              std::string disasm_params,
                              const char* asm_header) :
      architecture_string_(architecture),
      asm_header_(asm_header),
      assembler_cmd_name_(as),
      assembler_parameters_(as_params),
      objdump_cmd_name_(objdump),
      objdump_parameters_(objdump_params),
      disassembler_cmd_name_(disasm),
      disassembler_parameters_(disasm_params) {
    // Fake a runtime test for ScratchFile
    CommonRuntimeTest::SetUpAndroidDataDir(android_data_);
  }

  virtual ~AssemblerTestInfrastructure() {
    // We leave temporaries in case this failed so we can debug issues.
    CommonRuntimeTest::TearDownAndroidDataDir(android_data_, false);
    tmpnam_ = "";
  }

  // This is intended to be run as a test.
  bool CheckTools() {
    std::string asm_tool = FindTool(assembler_cmd_name_);
    if (!FileExists(asm_tool)) {
      LOG(ERROR) << "Could not find assembler from " << assembler_cmd_name_;
      LOG(ERROR) << "FindTool returned " << asm_tool;
      FindToolDump(assembler_cmd_name_);
      return false;
    }
    LOG(INFO) << "Chosen assembler command: " << GetAssemblerCommand();

    std::string objdump_tool = FindTool(objdump_cmd_name_);
    if (!FileExists(objdump_tool)) {
      LOG(ERROR) << "Could not find objdump from " << objdump_cmd_name_;
      LOG(ERROR) << "FindTool returned " << objdump_tool;
      FindToolDump(objdump_cmd_name_);
      return false;
    }
    LOG(INFO) << "Chosen objdump command: " << GetObjdumpCommand();

    // Disassembly is optional.
    std::string disassembler = GetDisassembleCommand();
    if (disassembler.length() != 0) {
      std::string disassembler_tool = FindTool(disassembler_cmd_name_);
      if (!FileExists(disassembler_tool)) {
        LOG(ERROR) << "Could not find disassembler from " << disassembler_cmd_name_;
        LOG(ERROR) << "FindTool returned " << disassembler_tool;
        FindToolDump(disassembler_cmd_name_);
        return false;
      }
      LOG(INFO) << "Chosen disassemble command: " << GetDisassembleCommand();
    } else {
      LOG(INFO) << "No disassembler given.";
    }

    return true;
  }

  // Driver() assembles and compares the results. If the results are not equal and we have a
  // disassembler, disassemble both and check whether they have the same mnemonics (in which case
  // we just warn).
  void Driver(const std::vector<uint8_t>& data,
              const std::string& assembly_text,
              const std::string& test_name) {
    EXPECT_NE(assembly_text.length(), 0U) << "Empty assembly";

    NativeAssemblerResult res;
    Compile(assembly_text, &res, test_name);

    EXPECT_TRUE(res.ok) << res.error_msg;
    if (!res.ok) {
      // No way of continuing.
      return;
    }

    if (data == *res.code) {
      Clean(&res);
    } else {
      if (DisassembleBinaries(data, *res.code, test_name)) {
        if (data.size() > res.code->size()) {
          // Fail this test with a fancy colored warning being printed.
          EXPECT_TRUE(false) << "Assembly code is not identical, but disassembly of machine code "
              "is equal: this implies sub-optimal encoding! Our code size=" << data.size() <<
              ", gcc size=" << res.code->size();
        } else {
          // Otherwise just print an info message and clean up.
          LOG(INFO) << "GCC chose a different encoding than ours, but the overall length is the "
              "same.";
          Clean(&res);
        }
      } else {
        // This will output the assembly.
        EXPECT_EQ(*res.code, data) << "Outputs (and disassembly) not identical.";
      }
    }
  }

 protected:
  // Return the host assembler command for this test.
  virtual std::string GetAssemblerCommand() {
    // Already resolved it once?
    if (resolved_assembler_cmd_.length() != 0) {
      return resolved_assembler_cmd_;
    }

    std::string line = FindTool(assembler_cmd_name_);
    if (line.length() == 0) {
      return line;
    }

    resolved_assembler_cmd_ = line + assembler_parameters_;

    return resolved_assembler_cmd_;
  }

  // Return the host objdump command for this test.
  virtual std::string GetObjdumpCommand() {
    // Already resolved it once?
    if (resolved_objdump_cmd_.length() != 0) {
      return resolved_objdump_cmd_;
    }

    std::string line = FindTool(objdump_cmd_name_);
    if (line.length() == 0) {
      return line;
    }

    resolved_objdump_cmd_ = line + objdump_parameters_;

    return resolved_objdump_cmd_;
  }

  // Return the host disassembler command for this test.
  virtual std::string GetDisassembleCommand() {
    // Already resolved it once?
    if (resolved_disassemble_cmd_.length() != 0) {
      return resolved_disassemble_cmd_;
    }

    std::string line = FindTool(disassembler_cmd_name_);
    if (line.length() == 0) {
      return line;
    }

    resolved_disassemble_cmd_ = line + disassembler_parameters_;

    return resolved_disassemble_cmd_;
  }

 private:
  // Structure to store intermediates and results.
  struct NativeAssemblerResult {
    bool ok;
    std::string error_msg;
    std::string base_name;
    std::unique_ptr<std::vector<uint8_t>> code;
    uintptr_t length;
  };

  // Compile the assembly file from_file to a binary file to_file. Returns true on success.
  bool Assemble(const char* from_file, const char* to_file, std::string* error_msg) {
    bool have_assembler = FileExists(FindTool(assembler_cmd_name_));
    EXPECT_TRUE(have_assembler) << "Cannot find assembler:" << GetAssemblerCommand();
    if (!have_assembler) {
      return false;
    }

    std::vector<std::string> args;

    // Encaspulate the whole command line in a single string passed to
    // the shell, so that GetAssemblerCommand() may contain arguments
    // in addition to the program name.
    args.push_back(GetAssemblerCommand());
    args.push_back("-o");
    args.push_back(to_file);
    args.push_back(from_file);
    std::string cmd = android::base::Join(args, ' ');

    args.clear();
    args.push_back("/bin/sh");
    args.push_back("-c");
    args.push_back(cmd);

    bool success = Exec(args, error_msg);
    if (!success) {
      LOG(ERROR) << "Assembler command line:";
      for (const std::string& arg : args) {
        LOG(ERROR) << arg;
      }
    }
    return success;
  }

  // Runs objdump -h on the binary file and extracts the first line with .text.
  // Returns "" on failure.
  std::string Objdump(const std::string& file) {
    bool have_objdump = FileExists(FindTool(objdump_cmd_name_));
    EXPECT_TRUE(have_objdump) << "Cannot find objdump: " << GetObjdumpCommand();
    if (!have_objdump) {
      return "";
    }

    std::string error_msg;
    std::vector<std::string> args;

    // Encaspulate the whole command line in a single string passed to
    // the shell, so that GetObjdumpCommand() may contain arguments
    // in addition to the program name.
    args.push_back(GetObjdumpCommand());
    args.push_back(file);
    args.push_back(">");
    args.push_back(file+".dump");
    std::string cmd = android::base::Join(args, ' ');

    args.clear();
    args.push_back("/bin/sh");
    args.push_back("-c");
    args.push_back(cmd);

    if (!Exec(args, &error_msg)) {
      EXPECT_TRUE(false) << error_msg;
    }

    std::ifstream dump(file+".dump");

    std::string line;
    bool found = false;
    while (std::getline(dump, line)) {
      if (line.find(".text") != line.npos) {
        found = true;
        break;
      }
    }

    dump.close();

    if (found) {
      return line;
    } else {
      return "";
    }
  }

  // Disassemble both binaries and compare the text.
  bool DisassembleBinaries(const std::vector<uint8_t>& data,
                           const std::vector<uint8_t>& as,
                           const std::string& test_name) {
    std::string disassembler = GetDisassembleCommand();
    if (disassembler.length() == 0) {
      LOG(WARNING) << "No dissassembler command.";
      return false;
    }

    std::string data_name = WriteToFile(data, test_name + ".ass");
    std::string error_msg;
    if (!DisassembleBinary(data_name, &error_msg)) {
      LOG(INFO) << "Error disassembling: " << error_msg;
      std::remove(data_name.c_str());
      return false;
    }

    std::string as_name = WriteToFile(as, test_name + ".gcc");
    if (!DisassembleBinary(as_name, &error_msg)) {
      LOG(INFO) << "Error disassembling: " << error_msg;
      std::remove(data_name.c_str());
      std::remove((data_name + ".dis").c_str());
      std::remove(as_name.c_str());
      return false;
    }

    bool result = CompareFiles(data_name + ".dis", as_name + ".dis");

    if (!kKeepDisassembledFiles) {
      std::remove(data_name.c_str());
      std::remove(as_name.c_str());
      std::remove((data_name + ".dis").c_str());
      std::remove((as_name + ".dis").c_str());
    }

    return result;
  }

  bool DisassembleBinary(const std::string& file, std::string* error_msg) {
    std::vector<std::string> args;

    // Encaspulate the whole command line in a single string passed to
    // the shell, so that GetDisassembleCommand() may contain arguments
    // in addition to the program name.
    args.push_back(GetDisassembleCommand());
    args.push_back(file);
    args.push_back("| sed -n \'/<.data>/,$p\' | sed -e \'s/.*://\'");
    args.push_back(">");
    args.push_back(file+".dis");
    std::string cmd = android::base::Join(args, ' ');

    args.clear();
    args.push_back("/bin/sh");
    args.push_back("-c");
    args.push_back(cmd);

    return Exec(args, error_msg);
  }

  std::string WriteToFile(const std::vector<uint8_t>& buffer, const std::string& test_name) {
    std::string file_name = GetTmpnam() + std::string("---") + test_name;
    const char* data = reinterpret_cast<const char*>(buffer.data());
    std::ofstream s_out(file_name + ".o");
    s_out.write(data, buffer.size());
    s_out.close();
    return file_name + ".o";
  }

  bool CompareFiles(const std::string& f1, const std::string& f2) {
    std::ifstream f1_in(f1);
    std::ifstream f2_in(f2);

    bool read1_ok, read2_ok;
    char c1, c2;
    do {
      read1_ok = static_cast<bool>(f1_in >> c1);
      read2_ok = static_cast<bool>(f2_in >> c2);
    } while (read1_ok && read2_ok && c1 == c2);
    return !read1_ok && !read2_ok;  // Did we reach the end of both streams?
  }

  // Compile the given assembly code and extract the binary, if possible. Put result into res.
  bool Compile(const std::string& assembly_code,
               NativeAssemblerResult* res,
               const std::string& test_name) {
    res->ok = false;
    res->code.reset(nullptr);

    res->base_name = GetTmpnam() + std::string("---") + test_name;

    // TODO: Lots of error checking.

    std::ofstream s_out(res->base_name + ".S");
    if (asm_header_ != nullptr) {
      s_out << asm_header_;
    }
    s_out << assembly_code;
    s_out.close();

    if (!Assemble((res->base_name + ".S").c_str(), (res->base_name + ".o").c_str(),
                  &res->error_msg)) {
      res->error_msg = "Could not compile.";
      return false;
    }

    std::string odump = Objdump(res->base_name + ".o");
    if (odump.length() == 0) {
      res->error_msg = "Objdump failed.";
      return false;
    }

    std::istringstream iss(odump);
    std::istream_iterator<std::string> start(iss);
    std::istream_iterator<std::string> end;
    std::vector<std::string> tokens(start, end);

    if (tokens.size() < OBJDUMP_SECTION_LINE_MIN_TOKENS) {
      res->error_msg = "Objdump output not recognized: too few tokens.";
      return false;
    }

    if (tokens[1] != ".text") {
      res->error_msg = "Objdump output not recognized: .text not second token.";
      return false;
    }

    std::string lengthToken = "0x" + tokens[2];
    std::istringstream(lengthToken) >> std::hex >> res->length;

    std::string offsetToken = "0x" + tokens[5];
    uintptr_t offset;
    std::istringstream(offsetToken) >> std::hex >> offset;

    std::ifstream obj(res->base_name + ".o");
    obj.seekg(offset);
    res->code.reset(new std::vector<uint8_t>(res->length));
    obj.read(reinterpret_cast<char*>(&(*res->code)[0]), res->length);
    obj.close();

    res->ok = true;
    return true;
  }

  // Remove temporary files.
  void Clean(const NativeAssemblerResult* res) {
    std::remove((res->base_name + ".S").c_str());
    std::remove((res->base_name + ".o").c_str());
    std::remove((res->base_name + ".o.dump").c_str());
  }

  // Check whether file exists. Is used for commands, so strips off any parameters: anything after
  // the first space. We skip to the last slash for this, so it should work with directories with
  // spaces.
  static bool FileExists(const std::string& file) {
    if (file.length() == 0) {
      return false;
    }

    // Need to strip any options.
    size_t last_slash = file.find_last_of('/');
    if (last_slash == std::string::npos) {
      // No slash, start looking at the start.
      last_slash = 0;
    }
    size_t space_index = file.find(' ', last_slash);

    if (space_index == std::string::npos) {
      std::ifstream infile(file.c_str());
      return infile.good();
    } else {
      std::string copy = file.substr(0, space_index - 1);

      struct stat buf;
      return stat(copy.c_str(), &buf) == 0;
    }
  }

  static std::string GetGCCRootPath() {
    return "prebuilts/gcc/linux-x86";
  }

  static std::string GetRootPath() {
    // 1) Check ANDROID_BUILD_TOP
    char* build_top = getenv("ANDROID_BUILD_TOP");
    if (build_top != nullptr) {
      return std::string(build_top) + "/";
    }

    // 2) Do cwd
    char temp[1024];
    return getcwd(temp, 1024) ? std::string(temp) + "/" : std::string("");
  }

  std::string FindTool(const std::string& tool_name) {
    // Find the current tool. Wild-card pattern is "arch-string*tool-name".
    std::string gcc_path = GetRootPath() + GetGCCRootPath();
    std::vector<std::string> args;
    args.push_back("find");
    args.push_back(gcc_path);
    args.push_back("-name");
    args.push_back(architecture_string_ + "*" + tool_name);
    args.push_back("|");
    args.push_back("sort");
    args.push_back("|");
    args.push_back("tail");
    args.push_back("-n");
    args.push_back("1");
    std::string tmp_file = GetTmpnam();
    args.push_back(">");
    args.push_back(tmp_file);
    std::string sh_args = android::base::Join(args, ' ');

    args.clear();
    args.push_back("/bin/sh");
    args.push_back("-c");
    args.push_back(sh_args);

    std::string error_msg;
    if (!Exec(args, &error_msg)) {
      EXPECT_TRUE(false) << error_msg;
      UNREACHABLE();
    }

    std::ifstream in(tmp_file.c_str());
    std::string line;
    if (!std::getline(in, line)) {
      in.close();
      std::remove(tmp_file.c_str());
      return "";
    }
    in.close();
    std::remove(tmp_file.c_str());
    return line;
  }

  // Helper for below. If name_predicate is empty, search for all files, otherwise use it for the
  // "-name" option.
  static void FindToolDumpPrintout(const std::string& name_predicate,
                                   const std::string& tmp_file) {
    std::string gcc_path = GetRootPath() + GetGCCRootPath();
    std::vector<std::string> args;
    args.push_back("find");
    args.push_back(gcc_path);
    if (!name_predicate.empty()) {
      args.push_back("-name");
      args.push_back(name_predicate);
    }
    args.push_back("|");
    args.push_back("sort");
    args.push_back(">");
    args.push_back(tmp_file);
    std::string sh_args = android::base::Join(args, ' ');

    args.clear();
    args.push_back("/bin/sh");
    args.push_back("-c");
    args.push_back(sh_args);

    std::string error_msg;
    if (!Exec(args, &error_msg)) {
      EXPECT_TRUE(false) << error_msg;
      UNREACHABLE();
    }

    LOG(ERROR) << "FindToolDump: gcc_path=" << gcc_path
               << " cmd=" << sh_args;
    std::ifstream in(tmp_file.c_str());
    if (in) {
      std::string line;
      while (std::getline(in, line)) {
        LOG(ERROR) << line;
      }
    }
    in.close();
    std::remove(tmp_file.c_str());
  }

  // For debug purposes.
  void FindToolDump(const std::string& tool_name) {
    // Check with the tool name.
    FindToolDumpPrintout(architecture_string_ + "*" + tool_name, GetTmpnam());
    FindToolDumpPrintout("", GetTmpnam());
  }

  // Use a consistent tmpnam, so store it.
  std::string GetTmpnam() {
    if (tmpnam_.length() == 0) {
      ScratchFile tmp;
      tmpnam_ = tmp.GetFilename() + "asm";
    }
    return tmpnam_;
  }

  static constexpr size_t OBJDUMP_SECTION_LINE_MIN_TOKENS = 6;

  std::string architecture_string_;
  const char* asm_header_;

  std::string assembler_cmd_name_;
  std::string assembler_parameters_;

  std::string objdump_cmd_name_;
  std::string objdump_parameters_;

  std::string disassembler_cmd_name_;
  std::string disassembler_parameters_;

  std::string resolved_assembler_cmd_;
  std::string resolved_objdump_cmd_;
  std::string resolved_disassemble_cmd_;

  std::string android_data_;

  DISALLOW_COPY_AND_ASSIGN(AssemblerTestInfrastructure);
};

}  // namespace art

#endif  // ART_COMPILER_UTILS_ASSEMBLER_TEST_BASE_H_
