/*
 * Copyright (C) 2015 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_OATDUMP_OATDUMP_TEST_H_
#define ART_OATDUMP_OATDUMP_TEST_H_

#include <sstream>
#include <string>
#include <vector>

#include "android-base/strings.h"

#include "arch/instruction_set.h"
#include "base/file_utils.h"
#include "base/os.h"
#include "base/unix_file/fd_file.h"
#include "base/utils.h"
#include "common_runtime_test.h"
#include "exec_utils.h"
#include "gc/heap.h"
#include "gc/space/image_space.h"

#include <sys/types.h>
#include <unistd.h>

namespace art {

class OatDumpTest : public CommonRuntimeTest {
 protected:
  virtual void SetUp() {
    CommonRuntimeTest::SetUp();
    core_art_location_ = GetCoreArtLocation();
    core_oat_location_ = GetSystemImageFilename(GetCoreOatLocation().c_str(), kRuntimeISA);
    tmp_dir_ = GetScratchDir();
  }

  virtual void TearDown() {
    ClearDirectory(tmp_dir_.c_str(), /*recursive*/ false);
    ASSERT_EQ(rmdir(tmp_dir_.c_str()), 0);
    CommonRuntimeTest::TearDown();
  }

  std::string GetScratchDir() {
    // ANDROID_DATA needs to be set
    CHECK_NE(static_cast<char*>(nullptr), getenv("ANDROID_DATA"));
    std::string dir = getenv("ANDROID_DATA");
    dir += "/oatdump-tmp-dir-XXXXXX";
    if (mkdtemp(&dir[0]) == nullptr) {
      PLOG(FATAL) << "mkdtemp(\"" << &dir[0] << "\") failed";
    }
    return dir;
  }

  // Linking flavor.
  enum Flavor {
    kDynamic,  // oatdump(d), dex2oat(d)
    kStatic,   // oatdump(d)s, dex2oat(d)s
  };

  // Returns path to the oatdump/dex2oat/dexdump binary.
  std::string GetExecutableFilePath(const char* name, bool is_debug, bool is_static, bool bitness) {
    std::string path = GetArtBinDir() + '/' + name;
    if (is_debug) {
      path += 'd';
    }
    if (is_static) {
      path += 's';
    }
    if (bitness) {
      path += Is64BitInstructionSet(kRuntimeISA) ? "64" : "32";
    }
    return path;
  }

  std::string GetExecutableFilePath(Flavor flavor, const char* name, bool bitness) {
    return GetExecutableFilePath(name, kIsDebugBuild, flavor == kStatic, bitness);
  }

  enum Mode {
    kModeOat,
    kModeCoreOat,
    kModeOatWithBootImage,
    kModeAppImage,
    kModeArt,
    kModeSymbolize,
  };

  // Display style.
  enum Display {
    kListOnly,
    kListAndCode
  };

  std::string GetAppBaseName() {
    // Use ProfileTestMultiDex as it contains references to boot image strings
    // that shall use different code for PIC and non-PIC.
    return "ProfileTestMultiDex";
  }

  void SetAppImageName(const std::string& name) {
    app_image_name_ = name;
  }

  std::string GetAppImageName() {
    if (app_image_name_.empty()) {
      app_image_name_ =  tmp_dir_ + "/" + GetAppBaseName() + ".art";
    }
    return app_image_name_;
  }

  std::string GetAppOdexName() {
    return tmp_dir_ + "/" + GetAppBaseName() + ".odex";
  }

  ::testing::AssertionResult GenerateAppOdexFile(Flavor flavor,
                                                 const std::vector<std::string>& args) {
    std::string dex2oat_path =
        GetExecutableFilePath(flavor, "dex2oat", /* bitness= */ kIsTargetBuild);
    std::vector<std::string> exec_argv = {
        dex2oat_path,
        "--runtime-arg",
        "-Xms64m",
        "--runtime-arg",
        "-Xmx512m",
        "--runtime-arg",
        "-Xnorelocate",
        "--runtime-arg",
        GetClassPathOption("-Xbootclasspath:", GetLibCoreDexFileNames()),
        "--runtime-arg",
        GetClassPathOption("-Xbootclasspath-locations:", GetLibCoreDexLocations()),
        "--boot-image=" + GetCoreArtLocation(),
        "--instruction-set=" + std::string(GetInstructionSetString(kRuntimeISA)),
        "--dex-file=" + GetTestDexFileName(GetAppBaseName().c_str()),
        "--oat-file=" + GetAppOdexName(),
        "--compiler-filter=speed"
    };
    exec_argv.insert(exec_argv.end(), args.begin(), args.end());

    auto post_fork_fn = []() {
      setpgid(0, 0);  // Change process groups, so we don't get reaped by ProcessManager.
                      // Ignore setpgid errors.
      return setenv("ANDROID_LOG_TAGS", "*:e", 1) == 0;  // We're only interested in errors and
                                                         // fatal logs.
    };

    std::string error_msg;
    ForkAndExecResult res = ForkAndExec(exec_argv, post_fork_fn, &error_msg);
    if (res.stage != ForkAndExecResult::kFinished) {
      return ::testing::AssertionFailure() << strerror(errno);
    }
    return res.StandardSuccess() ? ::testing::AssertionSuccess()
                                 : (::testing::AssertionFailure() << error_msg);
  }

  // Run the test with custom arguments.
  ::testing::AssertionResult Exec(Flavor flavor,
                                  Mode mode,
                                  const std::vector<std::string>& args,
                                  Display display,
                                  bool expect_failure = false) {
    std::string file_path = GetExecutableFilePath(flavor, "oatdump", /* bitness= */ false);

    if (!OS::FileExists(file_path.c_str())) {
      return ::testing::AssertionFailure() << file_path << " should be a valid file path";
    }

    // ScratchFile scratch;
    std::vector<std::string> exec_argv = { file_path };
    std::vector<std::string> expected_prefixes;
    if (mode == kModeSymbolize) {
      exec_argv.push_back("--symbolize=" + core_oat_location_);
      exec_argv.push_back("--output=" + core_oat_location_ + ".symbolize");
    } else {
      expected_prefixes.push_back("LOCATION:");
      expected_prefixes.push_back("MAGIC:");
      expected_prefixes.push_back("DEX FILE COUNT:");
      if (display == kListAndCode) {
        // Code and dex code do not show up if list only.
        expected_prefixes.push_back("DEX CODE:");
        expected_prefixes.push_back("CODE:");
        expected_prefixes.push_back("StackMap");
      }
      if (mode == kModeArt) {
        exec_argv.push_back("--runtime-arg");
        exec_argv.push_back(GetClassPathOption("-Xbootclasspath:", GetLibCoreDexFileNames()));
        exec_argv.push_back("--runtime-arg");
        exec_argv.push_back(
            GetClassPathOption("-Xbootclasspath-locations:", GetLibCoreDexLocations()));
        exec_argv.push_back("--image=" + core_art_location_);
        exec_argv.push_back("--instruction-set=" + std::string(
            GetInstructionSetString(kRuntimeISA)));
        expected_prefixes.push_back("IMAGE LOCATION:");
        expected_prefixes.push_back("IMAGE BEGIN:");
        expected_prefixes.push_back("kDexCaches:");
      } else if (mode == kModeOatWithBootImage) {
        exec_argv.push_back("--runtime-arg");
        exec_argv.push_back(GetClassPathOption("-Xbootclasspath:", GetLibCoreDexFileNames()));
        exec_argv.push_back("--runtime-arg");
        exec_argv.push_back(
            GetClassPathOption("-Xbootclasspath-locations:", GetLibCoreDexLocations()));
        exec_argv.push_back("--boot-image=" + GetCoreArtLocation());
        exec_argv.push_back("--instruction-set=" + std::string(
            GetInstructionSetString(kRuntimeISA)));
        exec_argv.push_back("--oat-file=" + GetAppOdexName());
      } else if (mode == kModeAppImage) {
        exec_argv.push_back("--runtime-arg");
        exec_argv.push_back(GetClassPathOption("-Xbootclasspath:", GetLibCoreDexFileNames()));
        exec_argv.push_back("--runtime-arg");
        exec_argv.push_back(
            GetClassPathOption("-Xbootclasspath-locations:", GetLibCoreDexLocations()));
        exec_argv.push_back("--image=" + GetCoreArtLocation());
        exec_argv.push_back("--instruction-set=" + std::string(
            GetInstructionSetString(kRuntimeISA)));
        exec_argv.push_back("--app-oat=" + GetAppOdexName());
        exec_argv.push_back("--app-image=" + GetAppImageName());
      } else if (mode == kModeCoreOat) {
        exec_argv.push_back("--oat-file=" + core_oat_location_);
        exec_argv.push_back("--dex-file=" + GetLibCoreDexFileNames()[0]);
      } else {
        CHECK_EQ(static_cast<size_t>(mode), static_cast<size_t>(kModeOat));
        exec_argv.push_back("--oat-file=" + GetAppOdexName());
      }
    }
    exec_argv.insert(exec_argv.end(), args.begin(), args.end());

    std::vector<bool> found(expected_prefixes.size(), false);
    auto line_handle_fn = [&found, &expected_prefixes](const char* line, size_t line_len) {
      if (line_len == 0) {
        return;
      }
      // Check contents.
      for (size_t i = 0; i < expected_prefixes.size(); ++i) {
        const std::string& expected = expected_prefixes[i];
        if (!found[i] &&
            line_len >= expected.length() &&
            memcmp(line, expected.c_str(), expected.length()) == 0) {
          found[i] = true;
        }
      }
    };

    static constexpr size_t kLineMax = 256;
    char line[kLineMax] = {};
    size_t line_len = 0;
    size_t total = 0;
    bool ignore_next_line = false;
    std::vector<char> error_buf;  // Buffer for debug output on error. Limited to 1M.
    auto line_buf_fn = [&](char* buf, size_t len) {
      total += len;

      if (len == 0 && line_len > 0 && !ignore_next_line) {
        // Everything done, handle leftovers.
        line_handle_fn(line, line_len);
      }

      if (len > 0) {
        size_t pos = error_buf.size();
        if (pos < MB) {
          error_buf.insert(error_buf.end(), buf, buf + len);
        }
      }

      while (len > 0) {
        // Copy buf into the free tail of the line buffer, and move input buffer along.
        size_t copy = std::min(kLineMax - line_len, len);
        memcpy(&line[line_len], buf, copy);
        buf += copy;
        len -= copy;

        // Skip spaces up to len, return count of removed spaces. Declare a lambda for reuse.
        auto trim_space = [&line](size_t len) {
          size_t spaces = 0;
          for (; spaces < len && isspace(line[spaces]); ++spaces) {}
          if (spaces > 0) {
            memmove(&line[0], &line[spaces], len - spaces);
          }
          return spaces;
        };
        // There can only be spaces if we freshly started a line.
        if (line_len == 0) {
          copy -= trim_space(copy);
        }

        // Scan for newline characters.
        size_t index = line_len;
        line_len += copy;
        while (index < line_len) {
          if (line[index] == '\n') {
            // Handle line.
            if (!ignore_next_line) {
              line_handle_fn(line, index);
            }
            // Move the rest to the front, but trim leading spaces.
            line_len -= index + 1;
            memmove(&line[0], &line[index + 1], line_len);
            line_len -= trim_space(line_len);
            index = 0;
            ignore_next_line = false;
          } else {
            index++;
          }
        }

        // Handle a full line without newline characters. Ignore the "next" line, as it is the
        // tail end of this.
        if (line_len == kLineMax) {
          if (!ignore_next_line) {
            line_handle_fn(line, kLineMax);
          }
          line_len = 0;
          ignore_next_line = true;
        }
      }
    };

    auto post_fork_fn = []() {
      setpgid(0, 0);  // Change process groups, so we don't get reaped by ProcessManager.
      return true;    // Ignore setpgid failures.
    };

    ForkAndExecResult res = ForkAndExec(exec_argv, post_fork_fn, line_buf_fn);
    if (res.stage != ForkAndExecResult::kFinished) {
      return ::testing::AssertionFailure() << strerror(errno);
    }
    error_buf.push_back(0);  // Make data a C string.

    if (!res.StandardSuccess()) {
      if (expect_failure && WIFEXITED(res.status_code)) {
        // Avoid crash as valid exit.
        return ::testing::AssertionSuccess();
      }
      return ::testing::AssertionFailure() << "Did not terminate successfully: " << res.status_code
          << " " << error_buf.data();
    } else if (expect_failure) {
      return ::testing::AssertionFailure() << "Expected failure";
    }

    if (mode == kModeSymbolize) {
      EXPECT_EQ(total, 0u);
    } else {
      EXPECT_GT(total, 0u);
    }

    bool result = true;
    std::ostringstream oss;
    for (size_t i = 0; i < expected_prefixes.size(); ++i) {
      if (!found[i]) {
        oss << "Did not find prefix " << expected_prefixes[i] << std::endl;
        result = false;
      }
    }
    if (!result) {
      oss << "Processed bytes " << total << ":" << std::endl;
    }

    return result ? ::testing::AssertionSuccess()
                  : (::testing::AssertionFailure() << oss.str() << error_buf.data());
  }

  std::string tmp_dir_;
  std::string app_image_name_;

 private:
  std::string core_art_location_;
  std::string core_oat_location_;
};

}  // namespace art

#endif  // ART_OATDUMP_OATDUMP_TEST_H_
