/*
 * Copyright (C) 2019 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.
 */

#include <stdio.h>

#include <memory>
#include <string>
#include <thread>
#include <vector>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <ziparchive/zip_writer.h>

#include "RegEx.h"
#include "cmd_api_impl.h"
#include "command.h"
#include "environment.h"
#include "event_type.h"
#include "utils.h"
#include "workload.h"

namespace simpleperf {
namespace {

const std::string SIMPLEPERF_DATA_DIR = "simpleperf_data";

class PrepareCommand : public Command {
 public:
  PrepareCommand()
      : Command("api-prepare", "Prepare recording via app api",
                // clang-format off
"Usage: simpleperf api-prepare [options]\n"
"--app <package_name>    the android application to record via app api\n"
"--days <days>           By default, the recording permission is reset after device reboot.\n"
"                        But on Android >= 13, we can use this option to set how long we want\n"
"                        the permission to last. It can last after device reboot.\n"
                // clang-format on
        ) {}
  bool Run(const std::vector<std::string>& args);

 private:
  bool ParseOptions(const std::vector<std::string>& args);
  std::optional<uint32_t> GetAppUid();

  std::string app_name_;
  uint64_t days_ = 0;
};

bool PrepareCommand::Run(const std::vector<std::string>& args) {
  if (!ParseOptions(args)) {
    return false;
  }
  // Enable profiling.
  if (GetAndroidVersion() >= 13 && !app_name_.empty() && days_ != 0) {
    // Enable app recording via persist properties.
    uint64_t duration_in_sec;
    uint64_t expiration_time;
    if (__builtin_mul_overflow(days_, 24 * 3600, &duration_in_sec) ||
        __builtin_add_overflow(time(nullptr), duration_in_sec, &expiration_time)) {
      expiration_time = UINT64_MAX;
    }
    std::optional<uint32_t> uid = GetAppUid();
    if (!uid) {
      return false;
    }
    if (!android::base::SetProperty("persist.simpleperf.profile_app_uid",
                                    std::to_string(uid.value())) ||
        !android::base::SetProperty("persist.simpleperf.profile_app_expiration_time",
                                    std::to_string(expiration_time))) {
      LOG(ERROR) << "failed to set system properties";
      return false;
    }
  } else {
    // Enable app recording via security.perf_harden.
    if (!CheckPerfEventLimit()) {
      return false;
    }
  }

  // Create tracepoint_events file.
  return EventTypeManager::Instance().WriteTracepointsToFile("/data/local/tmp/tracepoint_events");
}

bool PrepareCommand::ParseOptions(const std::vector<std::string>& args) {
  OptionValueMap options;
  std::vector<std::pair<OptionName, OptionValue>> ordered_options;
  static const OptionFormatMap option_formats = {
      {"--app", {OptionValueType::STRING, OptionType::SINGLE, AppRunnerType::NOT_ALLOWED}},
      {"--days", {OptionValueType::UINT, OptionType::SINGLE, AppRunnerType::NOT_ALLOWED}},
  };
  if (!PreprocessOptions(args, option_formats, &options, &ordered_options, nullptr)) {
    return false;
  }

  if (auto value = options.PullValue("--app"); value) {
    app_name_ = *value->str_value;
  }
  if (!options.PullUintValue("--days", &days_)) {
    return false;
  }
  return true;
}

std::optional<uint32_t> PrepareCommand::GetAppUid() {
  std::unique_ptr<FILE, decltype(&pclose)> fp(popen("pm list packages -U", "re"), pclose);
  std::string content;
  if (!fp || !android::base::ReadFdToString(fileno(fp.get()), &content)) {
    PLOG(ERROR) << "failed to run `pm list packages -U`";
    return std::nullopt;
  }
  auto re = RegEx::Create(R"(package:([\w\.]+)\s+uid:(\d+))");
  auto match = re->SearchAll(content);
  while (match->IsValid()) {
    std::string name = match->GetField(1);
    uint32_t uid;
    if (name == app_name_ && android::base::ParseUint(match->GetField(2), &uid)) {
      return uid;
    }
    match->MoveToNextMatch();
  }
  LOG(ERROR) << "failed to find package " << app_name_;
  return std::nullopt;
}

class CollectCommand : public Command {
 public:
  CollectCommand()
      : Command("api-collect", "Collect recording data generated by app api",
                // clang-format off
"Usage: simpleperf api-collect [options]\n"
"--app <package_name>    the android application having recording data\n"
"-o record_zipfile_path  the path to store recording data\n"
"                        Default is simpleperf_data.zip.\n"
#if 0
// Below options are only used internally and shouldn't be visible to the public.
"--in-app               We are already running in the app's context.\n"
"--out-fd <fd>          Write output to a file descriptor.\n"
"--stop-signal-fd <fd>  Stop recording when fd is readable.\n"
#endif
                // clang-format on
        ) {
  }
  bool Run(const std::vector<std::string>& args);

 private:
  bool ParseOptions(const std::vector<std::string>& args);
  void HandleStopSignal();
  bool CollectRecordingData();
  bool RemoveRecordingData();

  std::string app_name_;
  std::string output_filepath_ = "simpleperf_data.zip";
  bool in_app_context_ = false;
  android::base::unique_fd out_fd_;
  android::base::unique_fd stop_signal_fd_;
};

bool CollectCommand::Run(const std::vector<std::string>& args) {
  if (!ParseOptions(args)) {
    return false;
  }
  if (in_app_context_) {
    HandleStopSignal();
    return CollectRecordingData() && RemoveRecordingData();
  }
  return RunInAppContext(app_name_, Name(), args, 0, output_filepath_, false);
}

bool CollectCommand::ParseOptions(const std::vector<std::string>& args) {
  OptionValueMap options;
  std::vector<std::pair<OptionName, OptionValue>> ordered_options;
  if (!PreprocessOptions(args, GetApiCollectCmdOptionFormats(), &options, &ordered_options,
                         nullptr)) {
    return false;
  }

  if (auto value = options.PullValue("--app"); value) {
    app_name_ = *value->str_value;
  }
  in_app_context_ = options.PullBoolValue("--in-app");

  if (auto value = options.PullValue("-o"); value) {
    output_filepath_ = *value->str_value;
  }
  if (auto value = options.PullValue("--out-fd"); value) {
    out_fd_.reset(static_cast<int>(value->uint_value));
  }
  if (auto value = options.PullValue("--stop-signal-fd"); value) {
    stop_signal_fd_.reset(static_cast<int>(value->uint_value));
  }

  CHECK(options.values.empty());
  CHECK(ordered_options.empty());
  if (!in_app_context_) {
    if (app_name_.empty()) {
      LOG(ERROR) << "--app is missing";
      return false;
    }
  }
  return true;
}

void CollectCommand::HandleStopSignal() {
  int fd = stop_signal_fd_.release();
  std::thread thread([fd]() {
    char c;
    static_cast<void>(read(fd, &c, 1));
    exit(1);
  });
  thread.detach();
}

bool CollectCommand::CollectRecordingData() {
  std::unique_ptr<FILE, decltype(&fclose)> fp(android::base::Fdopen(std::move(out_fd_), "w"),
                                              fclose);
  if (fp == nullptr) {
    PLOG(ERROR) << "failed to call fdopen";
    return false;
  }
  std::vector<char> buffer(64 * 1024);
  ZipWriter zip_writer(fp.get());
  for (const auto& name : GetEntriesInDir(SIMPLEPERF_DATA_DIR)) {
    // No need to collect temporary files.
    const std::string path = SIMPLEPERF_DATA_DIR + "/" + name;
    if (android::base::StartsWith(name, "TemporaryFile-") || !IsRegularFile(path)) {
      continue;
    }
    int result = zip_writer.StartEntry(name.c_str(), ZipWriter::kCompress);
    if (result != 0) {
      LOG(ERROR) << "failed to start zip entry " << name << ": "
                 << zip_writer.ErrorCodeString(result);
      return false;
    }
    android::base::unique_fd in_fd(FileHelper::OpenReadOnly(path));
    if (in_fd == -1) {
      PLOG(ERROR) << "failed to open " << path;
      return false;
    }
    while (true) {
      ssize_t nread = TEMP_FAILURE_RETRY(read(in_fd, buffer.data(), buffer.size()));
      if (nread < 0) {
        PLOG(ERROR) << "failed to read " << path;
        return false;
      }
      if (nread == 0) {
        break;
      }
      result = zip_writer.WriteBytes(buffer.data(), nread);
      if (result != 0) {
        LOG(ERROR) << "failed to write zip entry " << name << ": "
                   << zip_writer.ErrorCodeString(result);
        return false;
      }
    }
    result = zip_writer.FinishEntry();
    if (result != 0) {
      LOG(ERROR) << "failed to finish zip entry " << name << ": "
                 << zip_writer.ErrorCodeString(result);
      return false;
    }
  }
  int result = zip_writer.Finish();
  if (result != 0) {
    LOG(ERROR) << "failed to finish zip writer: " << zip_writer.ErrorCodeString(result);
    return false;
  }
  return true;
}

bool CollectCommand::RemoveRecordingData() {
  return Workload::RunCmd({"rm", "-rf", SIMPLEPERF_DATA_DIR});
}
}  // namespace

void RegisterAPICommands() {
  RegisterCommand("api-prepare", [] { return std::unique_ptr<Command>(new PrepareCommand()); });
  RegisterCommand("api-collect", [] { return std::unique_ptr<Command>(new CollectCommand()); });
}

}  // namespace simpleperf
