/*
 * Copyright (C) 2016 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 "activity_manager.h"

#include <sys/stat.h>
#include <iostream>
#include <sstream>

#include "utils/clock.h"
#include "utils/current_process.h"
#include "utils/device_info.h"
#include "utils/filesystem_notifier.h"
#include "utils/trace.h"

using std::string;

namespace {
const char *const kAmExecutable = "/system/bin/am";
}

namespace profiler {

ActivityManager::ActivityManager()
    : bash_(new BashCommandRunner(kAmExecutable)) {}

bool ActivityManager::StartProfiling(const ProfilingMode profiling_mode,
                                     const string &app_package_name,
                                     int sampling_interval_us,
                                     string *trace_path, string *error_string) {
  Trace trace("CPU:StartProfiling ART");
  std::lock_guard<std::mutex> lock(profiled_lock_);

  if (IsAppProfiled(app_package_name)) {
    *error_string = "App is already being profiled with ART";
    return false;
  }
  *trace_path = this->GenerateTracePath(app_package_name);

  // Run command via actual am.
  std::ostringstream parameters;
  parameters << "profile start ";
  if (profiling_mode == ActivityManager::SAMPLING) {
    // A sample interval in microseconds is required after '--sampling'.
    // Note that '--sampling 0' would direct ART into instrumentation mode.
    // If there's no '--sampling X', instrumentation is used.
    parameters << "--sampling " << sampling_interval_us << " ";
  }
  if (DeviceInfo::feature_level() >= 26) {
    // Use streaming output mode on O or greater.
    parameters << "--streaming ";
  }
  parameters << app_package_name << " " << *trace_path;
  if (!bash_->Run(parameters.str(), error_string)) {
    *error_string = "Unable to run profile start command";
    return false;
  }
  AddProfiledApp(app_package_name, *trace_path);
  return true;
}

bool ActivityManager::StopProfiling(const string &app_package_name,
                                    bool need_result, string *error_string) {
  Trace trace("CPU:StopProfiling ART");
  std::lock_guard<std::mutex> lock(profiled_lock_);

  // Start monitoring trace events (to catch close) so this method only returns
  // when the generation of the trace file is finished.
  FileSystemNotifier notifier(GetProfiledAppTracePath(app_package_name),
                              FileSystemNotifier::CLOSE);

  RemoveProfiledApp(app_package_name);

  if (need_result) {
    if (!notifier.IsReadyToNotify()) {
      *error_string = "Unable to monitor trace file for completion";
      return false;
    }
  }

  // Run stop command via actual am.
  string parameters;
  parameters.append("profile stop ");
  parameters.append(app_package_name);
  if (!bash_->Run(parameters, error_string)) {
    *error_string = "Unable to run profile stop command";
    return false;
  }

  if (need_result) {
    // Wait until ART has finished writing the trace to the file and closed the
    // file.
    if (!notifier.WaitUntilEventOccurs()) {
      *error_string = "Wait for ART trace file failed.";
      return false;
    }
  }

  return true;
}

bool ActivityManager::TriggerHeapDump(int pid, const std::string &file_path,
                                      std::string *error_string) const {
  std::stringstream ss;
  ss << "dumpheap " << pid << " " << file_path;
  return bash_->Run(ss.str(), error_string);
}

std::string ActivityManager::GenerateTracePath(
    const std::string &app_package_name) const {
  // TODO: The activity manager should be a component of the daemon.
  // And it should use the daemon's steady clock.
  SteadyClock clock;
  std::stringstream path;
  path << CurrentProcess::dir();
  path << app_package_name;
  path << "-";
  path << clock.GetCurrentTime();
  path << ".art_trace";
  return path.str();
}

ActivityManager *ActivityManager::Instance() {
  static ActivityManager *instance = new ActivityManager();
  return instance;
}

bool ActivityManager::IsAppProfiled(const std::string &app_package_name) const {
  return profiled_.find(app_package_name) != profiled_.end();
}

void ActivityManager::AddProfiledApp(const std::string &app_package_name,
                                     const std::string &trace_path) {
  ArtOnGoingProfiling profilingEntry;
  profilingEntry.trace_path = trace_path;
  profilingEntry.app_pkg_name = app_package_name;
  profiled_[app_package_name] = profilingEntry;
}

void ActivityManager::RemoveProfiledApp(const std::string &app_package_name) {
  profiled_.erase(app_package_name);
}

string ActivityManager::GetProfiledAppTracePath(
    const std::string &app_package_name) const {
  auto it = profiled_.find(app_package_name);
  return it->second.trace_path;
}

}  // namespace profiler
