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

#include "lldb/Target/ThreadSpec.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/StructuredData.h"

using namespace lldb;
using namespace lldb_private;

const char *ThreadSpec::g_option_names[static_cast<uint32_t>(
    ThreadSpec::OptionNames::LastOptionName)]{"Index", "ID", "Name",
                                              "QueueName"};

ThreadSpec::ThreadSpec()
    : m_index(UINT32_MAX), m_tid(LLDB_INVALID_THREAD_ID), m_name(),
      m_queue_name() {}

ThreadSpec::ThreadSpec(const ThreadSpec &rhs)
    : m_index(rhs.m_index), m_tid(rhs.m_tid), m_name(rhs.m_name),
      m_queue_name(rhs.m_queue_name) {}

const ThreadSpec &ThreadSpec::operator=(const ThreadSpec &rhs) {
  m_index = rhs.m_index;
  m_tid = rhs.m_tid;
  m_name = rhs.m_name;
  m_queue_name = rhs.m_queue_name;
  return *this;
}

std::unique_ptr<ThreadSpec> ThreadSpec::CreateFromStructuredData(
    const StructuredData::Dictionary &spec_dict, Status &error) {
  uint32_t index = UINT32_MAX;
  lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
  llvm::StringRef name;
  llvm::StringRef queue_name;

  std::unique_ptr<ThreadSpec> thread_spec_up(new ThreadSpec());
  bool success = spec_dict.GetValueForKeyAsInteger(
      GetKey(OptionNames::ThreadIndex), index);
  if (success)
    thread_spec_up->SetIndex(index);

  success =
      spec_dict.GetValueForKeyAsInteger(GetKey(OptionNames::ThreadID), tid);
  if (success)
    thread_spec_up->SetTID(tid);

  success =
      spec_dict.GetValueForKeyAsString(GetKey(OptionNames::ThreadName), name);
  if (success)
    thread_spec_up->SetName(name);

  success = spec_dict.GetValueForKeyAsString(GetKey(OptionNames::ThreadName),
                                             queue_name);
  if (success)
    thread_spec_up->SetQueueName(queue_name);

  return thread_spec_up;
}

StructuredData::ObjectSP ThreadSpec::SerializeToStructuredData() {
  StructuredData::DictionarySP data_dict_sp(new StructuredData::Dictionary());

  if (m_index != UINT32_MAX)
    data_dict_sp->AddIntegerItem(GetKey(OptionNames::ThreadIndex), m_index);
  if (m_tid != LLDB_INVALID_THREAD_ID)
    data_dict_sp->AddIntegerItem(GetKey(OptionNames::ThreadID), m_tid);
  if (!m_name.empty())
    data_dict_sp->AddStringItem(GetKey(OptionNames::ThreadName), m_name);
  if (!m_queue_name.empty())
    data_dict_sp->AddStringItem(GetKey(OptionNames::QueueName), m_queue_name);

  return data_dict_sp;
}

const char *ThreadSpec::GetName() const {
  return m_name.empty() ? nullptr : m_name.c_str();
}

const char *ThreadSpec::GetQueueName() const {
  return m_queue_name.empty() ? nullptr : m_queue_name.c_str();
}

bool ThreadSpec::TIDMatches(Thread &thread) const {
  if (m_tid == LLDB_INVALID_THREAD_ID)
    return true;

  lldb::tid_t thread_id = thread.GetID();
  return TIDMatches(thread_id);
}

bool ThreadSpec::IndexMatches(Thread &thread) const {
  if (m_index == UINT32_MAX)
    return true;
  uint32_t index = thread.GetIndexID();
  return IndexMatches(index);
}

bool ThreadSpec::NameMatches(Thread &thread) const {
  if (m_name.empty())
    return true;

  const char *name = thread.GetName();
  return NameMatches(name);
}

bool ThreadSpec::QueueNameMatches(Thread &thread) const {
  if (m_queue_name.empty())
    return true;

  const char *queue_name = thread.GetQueueName();
  return QueueNameMatches(queue_name);
}

bool ThreadSpec::ThreadPassesBasicTests(Thread &thread) const {
  if (!HasSpecification())
    return true;

  if (!TIDMatches(thread))
    return false;

  if (!IndexMatches(thread))
    return false;

  if (!NameMatches(thread))
    return false;

  if (!QueueNameMatches(thread))
    return false;

  return true;
}

bool ThreadSpec::HasSpecification() const {
  return (m_index != UINT32_MAX || m_tid != LLDB_INVALID_THREAD_ID ||
          !m_name.empty() || !m_queue_name.empty());
}

void ThreadSpec::GetDescription(Stream *s, lldb::DescriptionLevel level) const {
  if (!HasSpecification()) {
    if (level == eDescriptionLevelBrief) {
      s->PutCString("thread spec: no ");
    }
  } else {
    if (level == eDescriptionLevelBrief) {
      s->PutCString("thread spec: yes ");
    } else {
      if (GetTID() != LLDB_INVALID_THREAD_ID)
        s->Printf("tid: 0x%" PRIx64 " ", GetTID());

      if (GetIndex() != UINT32_MAX)
        s->Printf("index: %d ", GetIndex());

      const char *name = GetName();
      if (name)
        s->Printf("thread name: \"%s\" ", name);

      const char *queue_name = GetQueueName();
      if (queue_name)
        s->Printf("queue name: \"%s\" ", queue_name);
    }
  }
}
