///===-- Activity.cpp ---------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <Availability.h>
#include <dlfcn.h>
#include <string>
#include <uuid/uuid.h>

#include "DNBDefs.h"
#include "Genealogy.h"
#include "GenealogySPI.h"
#include "MachThreadList.h"

//---------------------------
/// Constructor
//---------------------------

Genealogy::Genealogy()
    : m_os_activity_diagnostic_for_pid(nullptr),
      m_os_activity_iterate_processes(nullptr),
      m_os_activity_iterate_breadcrumbs(nullptr),
      m_os_activity_iterate_messages(nullptr),
      m_os_activity_iterate_activities(nullptr), m_os_trace_get_type(nullptr),
      m_os_trace_copy_formatted_message(nullptr),
      m_os_activity_for_thread(nullptr), m_os_activity_for_task_thread(nullptr),
      m_thread_activities(), m_process_executable_infos(),
      m_diagnosticd_call_timed_out(false) {
  m_os_activity_diagnostic_for_pid =
      (bool (*)(pid_t, os_activity_t, uint32_t, os_diagnostic_block_t))dlsym(
          RTLD_DEFAULT, "os_activity_diagnostic_for_pid");
  m_os_activity_iterate_processes =
      (void (*)(os_activity_process_list_t, bool (^)(os_activity_process_t)))
          dlsym(RTLD_DEFAULT, "os_activity_iterate_processes");
  m_os_activity_iterate_breadcrumbs =
      (void (*)(os_activity_process_t, bool (^)(os_activity_breadcrumb_t)))
          dlsym(RTLD_DEFAULT, "os_activity_iterate_breadcrumbs");
  m_os_activity_iterate_messages = (void (*)(
      os_trace_message_list_t, os_activity_process_t,
      bool (^)(os_trace_message_t)))dlsym(RTLD_DEFAULT,
                                          "os_activity_iterate_messages");
  m_os_activity_iterate_activities = (void (*)(
      os_activity_list_t, os_activity_process_t,
      bool (^)(os_activity_entry_t)))dlsym(RTLD_DEFAULT,
                                           "os_activity_iterate_activities");
  m_os_trace_get_type =
      (uint8_t(*)(os_trace_message_t))dlsym(RTLD_DEFAULT, "os_trace_get_type");
  m_os_trace_copy_formatted_message = (char *(*)(os_trace_message_t))dlsym(
      RTLD_DEFAULT, "os_trace_copy_formatted_message");
  m_os_activity_for_thread =
      (os_activity_t(*)(os_activity_process_t, uint64_t))dlsym(
          RTLD_DEFAULT, "os_activity_for_thread");
  m_os_activity_for_task_thread = (os_activity_t(*)(task_t, uint64_t))dlsym(
      RTLD_DEFAULT, "os_activity_for_task_thread");
  m_os_activity_messages_for_thread = (os_trace_message_list_t(*)(
      os_activity_process_t process, os_activity_t activity,
      uint64_t thread_id))dlsym(RTLD_DEFAULT,
                                "os_activity_messages_for_thread");
}

Genealogy::ThreadActivitySP
Genealogy::GetGenealogyInfoForThread(pid_t pid, nub_thread_t tid,
                                     const MachThreadList &thread_list,
                                     task_t task, bool &timed_out) {
  ThreadActivitySP activity;
  //
  // if we've timed out trying to get the activities, don't try again at this
  // process stop.
  // (else we'll need to hit the timeout for every thread we're asked about.)
  // We'll try again at the next public stop.

  if (m_thread_activities.size() == 0 &&
      m_diagnosticd_call_timed_out == false) {
    GetActivities(pid, thread_list, task);
  }
  std::map<nub_thread_t, ThreadActivitySP>::const_iterator search;
  search = m_thread_activities.find(tid);
  if (search != m_thread_activities.end()) {
    activity = search->second;
  }
  timed_out = m_diagnosticd_call_timed_out;
  return activity;
}

void Genealogy::Clear() {
  m_thread_activities.clear();
  m_diagnosticd_call_timed_out = false;
}

void Genealogy::GetActivities(pid_t pid, const MachThreadList &thread_list,
                              task_t task) {
  if (m_os_activity_diagnostic_for_pid != nullptr &&
      m_os_activity_iterate_processes != nullptr &&
      m_os_activity_iterate_breadcrumbs != nullptr &&
      m_os_activity_iterate_messages != nullptr &&
      m_os_activity_iterate_activities != nullptr &&
      m_os_trace_get_type != nullptr &&
      m_os_trace_copy_formatted_message != nullptr &&
      (m_os_activity_for_thread != nullptr ||
       m_os_activity_for_task_thread != nullptr)) {
    __block dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    __block BreadcrumbList breadcrumbs;
    __block ActivityList activities;
    __block MessageList messages;
    __block std::map<nub_thread_t, uint64_t> thread_activity_mapping;

    os_activity_diagnostic_flag_t flags =
        OS_ACTIVITY_DIAGNOSTIC_ALL_ACTIVITIES |
        OS_ACTIVITY_DIAGNOSTIC_PROCESS_ONLY;
    if (m_os_activity_diagnostic_for_pid(
            pid, 0, flags, ^(os_activity_process_list_t processes, int error) {
              if (error == 0) {
                m_os_activity_iterate_processes(processes, ^bool(
                                                    os_activity_process_t
                                                        process_info) {
                  if (pid == process_info->pid) {
                    // Collect all the Breadcrumbs
                    m_os_activity_iterate_breadcrumbs(
                        process_info,
                        ^bool(os_activity_breadcrumb_t breadcrumb) {
                          Breadcrumb bc;
                          bc.breadcrumb_id = breadcrumb->breadcrumb_id;
                          bc.activity_id = breadcrumb->activity_id;
                          bc.timestamp = breadcrumb->timestamp;
                          if (breadcrumb->name)
                            bc.name = breadcrumb->name;
                          breadcrumbs.push_back(bc);
                          return true;
                        });

                    // Collect all the Activites
                    m_os_activity_iterate_activities(
                        process_info->activities, process_info,
                        ^bool(os_activity_entry_t activity) {
                          Activity ac;
                          ac.activity_start = activity->activity_start;
                          ac.activity_id = activity->activity_id;
                          ac.parent_id = activity->parent_id;
                          if (activity->activity_name)
                            ac.activity_name = activity->activity_name;
                          if (activity->reason)
                            ac.reason = activity->reason;
                          activities.push_back(ac);
                          return true;
                        });

                    // Collect all the Messages -- messages not associated with
                    // any thread
                    m_os_activity_iterate_messages(
                        process_info->messages, process_info,
                        ^bool(os_trace_message_t trace_msg) {
                          Message msg;
                          msg.timestamp = trace_msg->timestamp;
                          msg.trace_id = trace_msg->trace_id;
                          msg.thread = trace_msg->thread;
                          msg.type = m_os_trace_get_type(trace_msg);
                          msg.activity_id = 0;
                          if (trace_msg->image_uuid && trace_msg->image_path) {
                            ProcessExecutableInfoSP process_info_sp(
                                new ProcessExecutableInfo());
                            uuid_copy(process_info_sp->image_uuid,
                                      trace_msg->image_uuid);
                            process_info_sp->image_path = trace_msg->image_path;
                            msg.process_info_index =
                                AddProcessExecutableInfo(process_info_sp);
                          }
                          const char *message_text =
                              m_os_trace_copy_formatted_message(trace_msg);
                          if (message_text)
                            msg.message = message_text;
                          messages.push_back(msg);
                          return true;
                        });

                    // Discover which activities are said to be running on
                    // threads currently
                    const nub_size_t num_threads = thread_list.NumThreads();
                    for (nub_size_t i = 0; i < num_threads; ++i) {
                      nub_thread_t thread_id = thread_list.ThreadIDAtIndex(i);
                      os_activity_t act = 0;
                      if (m_os_activity_for_task_thread != nullptr) {
                        act = m_os_activity_for_task_thread(task, thread_id);
                      } else if (m_os_activity_for_thread != nullptr) {
                        act = m_os_activity_for_thread(process_info, thread_id);
                      }
                      if (act != 0)
                        thread_activity_mapping[thread_id] = act;
                    }

                    // Collect all Messages -- messages associated with a thread

                    // When there's no genealogy information, an early version
                    // of os_activity_messages_for_thread
                    // can crash in rare circumstances.  Check to see if this
                    // process has any activities before
                    // making the call to get messages.
                    if (process_info->activities != nullptr &&
                        thread_activity_mapping.size() > 0) {
                      std::map<nub_thread_t, uint64_t>::const_iterator iter;
                      for (iter = thread_activity_mapping.begin();
                           iter != thread_activity_mapping.end(); ++iter) {
                        nub_thread_t thread_id = iter->first;
                        os_activity_t act = iter->second;
                        os_trace_message_list_t this_thread_messages =
                            m_os_activity_messages_for_thread(process_info, act,
                                                              thread_id);
                        m_os_activity_iterate_messages(
                            this_thread_messages, process_info,
                            ^bool(os_trace_message_t trace_msg) {
                              Message msg;
                              msg.timestamp = trace_msg->timestamp;
                              msg.trace_id = trace_msg->trace_id;
                              msg.thread = trace_msg->thread;
                              msg.type = m_os_trace_get_type(trace_msg);
                              msg.activity_id = act;
                              if (trace_msg->image_uuid &&
                                  trace_msg->image_path) {
                                ProcessExecutableInfoSP process_info_sp(
                                    new ProcessExecutableInfo());
                                uuid_copy(process_info_sp->image_uuid,
                                          trace_msg->image_uuid);
                                process_info_sp->image_path =
                                    trace_msg->image_path;
                                msg.process_info_index =
                                    AddProcessExecutableInfo(process_info_sp);
                              }
                              const char *message_text =
                                  m_os_trace_copy_formatted_message(trace_msg);
                              if (message_text)
                                msg.message = message_text;
                              messages.push_back(msg);
                              return true;
                            });
                      }
                    }
                  }
                  return true;
                });
              }
              dispatch_semaphore_signal(semaphore);
            }) == true) {
      // Wait for the diagnosticd xpc calls to all finish up -- or half a second
      // to elapse.
      dispatch_time_t timeout =
          dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC / 2);
      bool success = dispatch_semaphore_wait(semaphore, timeout) == 0;
      if (!success) {
        m_diagnosticd_call_timed_out = true;
        return;
      }
    }

    // breadcrumbs, activities, and messages have all now been filled in.

    std::map<nub_thread_t, uint64_t>::const_iterator iter;
    for (iter = thread_activity_mapping.begin();
         iter != thread_activity_mapping.end(); ++iter) {
      nub_thread_t thread_id = iter->first;
      uint64_t activity_id = iter->second;
      ActivityList::const_iterator activity_search;
      for (activity_search = activities.begin();
           activity_search != activities.end(); ++activity_search) {
        if (activity_search->activity_id == activity_id) {
          ThreadActivitySP thread_activity_sp(new ThreadActivity());
          thread_activity_sp->current_activity = *activity_search;

          BreadcrumbList::const_iterator breadcrumb_search;
          for (breadcrumb_search = breadcrumbs.begin();
               breadcrumb_search != breadcrumbs.end(); ++breadcrumb_search) {
            if (breadcrumb_search->activity_id == activity_id) {
              thread_activity_sp->breadcrumbs.push_back(*breadcrumb_search);
            }
          }
          MessageList::const_iterator message_search;
          for (message_search = messages.begin();
               message_search != messages.end(); ++message_search) {
            if (message_search->thread == thread_id) {
              thread_activity_sp->messages.push_back(*message_search);
            }
          }

          m_thread_activities[thread_id] = thread_activity_sp;
          break;
        }
      }
    }
  }
}

uint32_t
Genealogy::AddProcessExecutableInfo(ProcessExecutableInfoSP process_exe_info) {
  const uint32_t info_size =
      static_cast<uint32_t>(m_process_executable_infos.size());
  for (uint32_t idx = 0; idx < info_size; ++idx) {
    if (uuid_compare(m_process_executable_infos[idx]->image_uuid,
                     process_exe_info->image_uuid) == 0) {
      return idx + 1;
    }
  }
  m_process_executable_infos.push_back(process_exe_info);
  return info_size + 1;
}

Genealogy::ProcessExecutableInfoSP
Genealogy::GetProcessExecutableInfosAtIndex(size_t idx) {
  ProcessExecutableInfoSP info_sp;
  if (idx > 0) {
    idx--;
    if (idx <= m_process_executable_infos.size()) {
      info_sp = m_process_executable_infos[idx];
    }
  }
  return info_sp;
}
