/*
 * 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/unix_file/fd_file.h"
#include "common_runtime_test.h"
#include "exec_utils.h"
#include "gc/heap.h"
#include "gc/space/image_space.h"
#include "os.h"
#include "utils.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);
  }

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

  // Returns path to the oatdump binary.
  std::string GetOatDumpFilePath(Flavor flavor) {
    std::string root = GetTestAndroidRoot();
    root += "/bin/oatdump";
    if (kIsDebugBuild) {
      root += "d";
    }
    if (flavor == kStatic) {
      root += "s";
    }
    return root;
  }

  enum Mode {
    kModeOat,
    kModeArt,
    kModeSymbolize,
  };

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

  // Run the test with custom arguments.
  bool Exec(Flavor flavor,
            Mode mode,
            const std::vector<std::string>& args,
            Display display,
            std::string* error_msg) {
    std::string file_path = GetOatDumpFilePath(flavor);

    EXPECT_TRUE(OS::FileExists(file_path.c_str())) << 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("Dex file data for");
      expected_prefixes.push_back("Num string ids:");
      expected_prefixes.push_back("Num field ids:");
      expected_prefixes.push_back("Num method ids:");
      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("CodeInfoEncoding");
        expected_prefixes.push_back("CodeInfoInlineInfo");
      }
      if (mode == kModeArt) {
        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 {
        CHECK_EQ(static_cast<size_t>(mode), static_cast<size_t>(kModeOat));
        exec_argv.push_back("--oat-file=" + core_oat_location_);
      }
    }
    exec_argv.insert(exec_argv.end(), args.begin(), args.end());

    bool result = true;
    // We must set --android-root.
    int link[2];
    if (pipe(link) == -1) {
      *error_msg = strerror(errno);
      return false;
    }

    const pid_t pid = fork();
    if (pid == -1) {
      *error_msg = strerror(errno);
      return false;
    }

    if (pid == 0) {
      dup2(link[1], STDOUT_FILENO);
      close(link[0]);
      close(link[1]);
      // change process groups, so we don't get reaped by ProcessManager
      setpgid(0, 0);
      // Use execv here rather than art::Exec to avoid blocking on waitpid here.
      std::vector<char*> argv;
      for (size_t i = 0; i < exec_argv.size(); ++i) {
        argv.push_back(const_cast<char*>(exec_argv[i].c_str()));
      }
      argv.push_back(nullptr);
      UNUSED(execv(argv[0], &argv[0]));
      const std::string command_line(android::base::Join(exec_argv, ' '));
      PLOG(ERROR) << "Failed to execv(" << command_line << ")";
      // _exit to avoid atexit handlers in child.
      _exit(1);
    } else {
      close(link[1]);
      static const size_t kLineMax = 256;
      char line[kLineMax] = {};
      size_t line_len = 0;
      size_t total = 0;
      std::vector<bool> found(expected_prefixes.size(), false);
      while (true) {
        while (true) {
          size_t spaces = 0;
          // Trim spaces at the start of the line.
          for (; spaces < line_len && isspace(line[spaces]); ++spaces) {}
          if (spaces > 0) {
            line_len -= spaces;
            memmove(&line[0], &line[spaces], line_len);
          }
          ssize_t bytes_read =
              TEMP_FAILURE_RETRY(read(link[0], &line[line_len], kLineMax - line_len));
          if (bytes_read <= 0) {
            break;
          }
          line_len += bytes_read;
          total += bytes_read;
        }
        if (line_len == 0) {
          break;
        }
        // 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;
          }
        }
        // Skip to next line.
        size_t next_line = 0;
        for (; next_line + 1 < line_len && line[next_line] != '\n'; ++next_line) {}
        line_len -= next_line + 1;
        memmove(&line[0], &line[next_line + 1], line_len);
      }
      if (mode == kModeSymbolize) {
        EXPECT_EQ(total, 0u);
      } else {
        EXPECT_GT(total, 0u);
      }
      LOG(INFO) << "Processed bytes " << total;
      close(link[0]);
      int status = 0;
      if (waitpid(pid, &status, 0) != -1) {
        result = (status == 0);
      }

      for (size_t i = 0; i < expected_prefixes.size(); ++i) {
        if (!found[i]) {
          LOG(ERROR) << "Did not find prefix " << expected_prefixes[i];
          result = false;
        }
      }
    }

    return result;
  }

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

}  // namespace art

#endif  // ART_OATDUMP_OATDUMP_TEST_H_
