//===-- BreakpointLocation.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/lldb-python.h"

// C Includes
// C++ Includes
#include <string>

// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private-log.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointID.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"

using namespace lldb;
using namespace lldb_private;

BreakpointLocation::BreakpointLocation
(
    break_id_t loc_id,
    Breakpoint &owner,
    const Address &addr,
    lldb::tid_t tid,
    bool hardware
) :
    StoppointLocation (loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware),
    m_being_created(true),
    m_address (addr),
    m_owner (owner),
    m_options_ap (),
    m_bp_site_sp (),
    m_condition_mutex ()
{
    SetThreadID (tid);
    m_being_created = false;
}

BreakpointLocation::~BreakpointLocation()
{
    ClearBreakpointSite();
}

lldb::addr_t
BreakpointLocation::GetLoadAddress () const
{
    return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget());
}

Address &
BreakpointLocation::GetAddress ()
{
    return m_address;
}

Breakpoint &
BreakpointLocation::GetBreakpoint ()
{
    return m_owner;
}

bool
BreakpointLocation::IsEnabled () const
{
    if (!m_owner.IsEnabled())
        return false;
    else if (m_options_ap.get() != NULL)
        return m_options_ap->IsEnabled();
    else
        return true;
}

void
BreakpointLocation::SetEnabled (bool enabled)
{
    GetLocationOptions()->SetEnabled(enabled);
    if (enabled)
    {
        ResolveBreakpointSite();
    }
    else
    {
        ClearBreakpointSite();
    }
    SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
}

void
BreakpointLocation::SetThreadID (lldb::tid_t thread_id)
{
    if (thread_id != LLDB_INVALID_THREAD_ID)
        GetLocationOptions()->SetThreadID(thread_id);
    else
    {
        // If we're resetting this to an invalid thread id, then
        // don't make an options pointer just to do that.
        if (m_options_ap.get() != NULL)
            m_options_ap->SetThreadID (thread_id);
    }
    SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
}

lldb::tid_t
BreakpointLocation::GetThreadID ()
{
    if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
        return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID();
    else
        return LLDB_INVALID_THREAD_ID;
}

void
BreakpointLocation::SetThreadIndex (uint32_t index)
{
    if (index != 0)
        GetLocationOptions()->GetThreadSpec()->SetIndex(index);
    else
    {
        // If we're resetting this to an invalid thread id, then
        // don't make an options pointer just to do that.
        if (m_options_ap.get() != NULL)
            m_options_ap->GetThreadSpec()->SetIndex(index);
    }
    SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
                        
}

uint32_t
BreakpointLocation::GetThreadIndex() const
{
    if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
        return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex();
    else
        return 0;
}

void
BreakpointLocation::SetThreadName (const char *thread_name)
{
    if (thread_name != NULL)
        GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
    else
    {
        // If we're resetting this to an invalid thread id, then
        // don't make an options pointer just to do that.
        if (m_options_ap.get() != NULL)
            m_options_ap->GetThreadSpec()->SetName(thread_name);
    }
    SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
}

const char *
BreakpointLocation::GetThreadName () const
{
    if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
        return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName();
    else
        return NULL;
}

void 
BreakpointLocation::SetQueueName (const char *queue_name)
{
    if (queue_name != NULL)
        GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
    else
    {
        // If we're resetting this to an invalid thread id, then
        // don't make an options pointer just to do that.
        if (m_options_ap.get() != NULL)
            m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
    }
    SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
}

const char *
BreakpointLocation::GetQueueName () const
{
    if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
        return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName();
    else
        return NULL;
}

bool
BreakpointLocation::InvokeCallback (StoppointCallbackContext *context)
{
    if (m_options_ap.get() != NULL && m_options_ap->HasCallback())
        return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID());
    else    
        return m_owner.InvokeCallback (context, GetID());
}

void
BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton,
                 bool is_synchronous)
{
    // The default "Baton" class will keep a copy of "baton" and won't free
    // or delete it when it goes goes out of scope.
    GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
    SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
}

void
BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp,
                 bool is_synchronous)
{
    GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous);
    SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
}


void
BreakpointLocation::ClearCallback ()
{
    GetLocationOptions()->ClearCallback();
}

void 
BreakpointLocation::SetCondition (const char *condition)
{
    GetLocationOptions()->SetCondition (condition);
    SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged);
}

const char *
BreakpointLocation::GetConditionText (size_t *hash) const
{
    return GetOptionsNoCreate()->GetConditionText(hash);
}

bool
BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
{
    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
 
    Mutex::Locker evaluation_locker(m_condition_mutex);
    
    size_t condition_hash;
    const char *condition_text = GetConditionText(&condition_hash);
    
    if (!condition_text)
    {
        m_user_expression_sp.reset();
        return false;
    }
    
    if (condition_hash != m_condition_hash ||
        !m_user_expression_sp ||
        !m_user_expression_sp->MatchesContext(exe_ctx))
    {
        m_user_expression_sp.reset(new ClangUserExpression(condition_text,
                                                           NULL,
                                                           lldb::eLanguageTypeUnknown,
                                                           ClangUserExpression::eResultTypeAny));
        
        StreamString errors;
        
        if (!m_user_expression_sp->Parse(errors,
                                         exe_ctx,
                                         eExecutionPolicyOnlyWhenNeeded,
                                         true))
        {
            error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s",
                                           errors.GetData());
            m_user_expression_sp.reset();
            return false;
        }
        
        m_condition_hash = condition_hash;
    }

    // We need to make sure the user sees any parse errors in their condition, so we'll hook the
    // constructor errors up to the debugger's Async I/O.
        
    ValueObjectSP result_value_sp;
    const bool unwind_on_error = true;
    const bool ignore_breakpoints = true;
    const bool try_all_threads = true;
    
    Error expr_error;
    
    StreamString execution_errors;
    
    ClangExpressionVariableSP result_variable_sp;
    
    ExecutionResults result_code =
    m_user_expression_sp->Execute(execution_errors,
                                  exe_ctx,
                                  unwind_on_error,
                                  ignore_breakpoints,
                                  m_user_expression_sp,
                                  result_variable_sp,
                                  try_all_threads,
                                  ClangUserExpression::kDefaultTimeout);
    
    bool ret;
    
    if (result_code == eExecutionCompleted)
    {
        if (!result_variable_sp)
        {
            ret = false;
            error.SetErrorString("Expression did not return a result");
        }
        
        result_value_sp = result_variable_sp->GetValueObject();

        if (result_value_sp)
        {
            Scalar scalar_value;
            if (result_value_sp->ResolveValue (scalar_value))
            {
                if (scalar_value.ULongLong(1) == 0)
                    ret = false;
                else
                    ret = true;
                if (log)
                    log->Printf("Condition successfully evaluated, result is %s.\n",
                                ret ? "true" : "false");
            }
            else
            {
                ret = false;
                error.SetErrorString("Failed to get an integer result from the expression");
            }
        }
        else
        {
            ret = false;
            error.SetErrorString("Failed to get any result from the expression");
        }
    }
    else
    {
        ret = false;
        error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData());
    }
    
    return ret;
}

uint32_t
BreakpointLocation::GetIgnoreCount ()
{
    return GetOptionsNoCreate()->GetIgnoreCount();
}

void
BreakpointLocation::SetIgnoreCount (uint32_t n)
{
    GetLocationOptions()->SetIgnoreCount(n);
    SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged);
}

void
BreakpointLocation::DecrementIgnoreCount()
{
    if (m_options_ap.get() != NULL)
    {
        uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
        if (loc_ignore != 0)
            m_options_ap->SetIgnoreCount(loc_ignore - 1);
    }
}

bool
BreakpointLocation::IgnoreCountShouldStop()
{
    if (m_options_ap.get() != NULL)
    {
        uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
        if (loc_ignore != 0)
        {
            m_owner.DecrementIgnoreCount();
            DecrementIgnoreCount();          // Have to decrement our owners' ignore count, since it won't get a
                                             // chance to.
            return false;
        }
    }
    return true;
}

const BreakpointOptions *
BreakpointLocation::GetOptionsNoCreate () const
{
    if (m_options_ap.get() != NULL)
        return m_options_ap.get();
    else
        return m_owner.GetOptions ();
}

BreakpointOptions *
BreakpointLocation::GetLocationOptions ()
{
    // If we make the copy we don't copy the callbacks because that is potentially 
    // expensive and we don't want to do that for the simple case where someone is
    // just disabling the location.
    if (m_options_ap.get() == NULL)
        m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ()));
    
    return m_options_ap.get();
}

bool
BreakpointLocation::ValidForThisThread (Thread *thread)
{
    return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate());
}

// RETURNS - true if we should stop at this breakpoint, false if we
// should continue.  Note, we don't check the thread spec for the breakpoint
// here, since if the breakpoint is not for this thread, then the event won't
// even get reported, so the check is redundant.

bool
BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
{
    bool should_stop = true;
    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);

    IncrementHitCount();

    if (!IsEnabled())
        return false;

    if (!IgnoreCountShouldStop())
        return false;
    
    if (!m_owner.IgnoreCountShouldStop())
        return false;

    // We only run synchronous callbacks in ShouldStop:
    context->is_synchronous = true;
    should_stop = InvokeCallback (context);
    
    if (log)
    {
        StreamString s;
        GetDescription (&s, lldb::eDescriptionLevelVerbose);
        log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing");
    }
    
    return should_stop;
}

bool
BreakpointLocation::IsResolved () const
{
    return m_bp_site_sp.get() != NULL;
}

lldb::BreakpointSiteSP
BreakpointLocation::GetBreakpointSite() const
{
    return m_bp_site_sp;
}

bool
BreakpointLocation::ResolveBreakpointSite ()
{
    if (m_bp_site_sp)
        return true;

    Process *process = m_owner.GetTarget().GetProcessSP().get();
    if (process == NULL)
        return false;

    if (m_owner.GetTarget().GetSectionLoadList().IsEmpty())
        return false;

    lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), false);

    if (new_id == LLDB_INVALID_BREAK_ID)
    {
        Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
        if (log)
            log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n",
                          m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()));
        return false;
    }

    return true;
}

bool
BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp)
{
    m_bp_site_sp = bp_site_sp;
    return true;
}

bool
BreakpointLocation::ClearBreakpointSite ()
{
    if (m_bp_site_sp.get())
    {
        m_owner.GetTarget().GetProcessSP()->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(), 
                                                                           GetID(), m_bp_site_sp);
        m_bp_site_sp.reset();
        return true;
    }
    return false;
}

void
BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
    SymbolContext sc;
    
    // If the description level is "initial" then the breakpoint is printing out our initial state,
    // and we should let it decide how it wants to print our label.
    if (level != eDescriptionLevelInitial)
    {
        s->Indent();
        BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
    }
    
    if (level == lldb::eDescriptionLevelBrief)
        return;

    if (level != eDescriptionLevelInitial)
        s->PutCString(": ");

    if (level == lldb::eDescriptionLevelVerbose)
        s->IndentMore();

    if (m_address.IsSectionOffset())
    {
        m_address.CalculateSymbolContext(&sc);

        if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial)
        {
            s->PutCString("where = ");
            sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false);
        }
        else
        {
            if (sc.module_sp)
            {
                s->EOL();
                s->Indent("module = ");
                sc.module_sp->GetFileSpec().Dump (s);
            }

            if (sc.comp_unit != NULL)
            {
                s->EOL();
                s->Indent("compile unit = ");
                static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s);

                if (sc.function != NULL)
                {
                    s->EOL();
                    s->Indent("function = ");
                    s->PutCString (sc.function->GetMangled().GetName().AsCString("<unknown>"));
                }

                if (sc.line_entry.line > 0)
                {
                    s->EOL();
                    s->Indent("location = ");
                    sc.line_entry.DumpStopContext (s, true);
                }

            }
            else
            {
                // If we don't have a comp unit, see if we have a symbol we can print.
                if (sc.symbol)
                {
                    s->EOL();
                    s->Indent("symbol = ");
                    s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>"));
                }
            }
        }
    }

    if (level == lldb::eDescriptionLevelVerbose)
    {
        s->EOL();
        s->Indent();
    }
    
    if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
        s->Printf (", ");
    s->Printf ("address = ");
    
    ExecutionContextScope *exe_scope = NULL;
    Target *target = &m_owner.GetTarget();
    if (target)
        exe_scope = target->GetProcessSP().get();
    if (exe_scope == NULL)
        exe_scope = target;

    if (eDescriptionLevelInitial)
        m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
    else
        m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);

    if (level == lldb::eDescriptionLevelVerbose)
    {
        s->EOL();
        s->Indent();
        s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");

        s->Indent();
        s->Printf ("hit count = %-4u\n", GetHitCount());

        if (m_options_ap.get())
        {
            s->Indent();
            m_options_ap->GetDescription (s, level);
            s->EOL();
        }
        s->IndentLess();
    }
    else if (level != eDescriptionLevelInitial)
    {
        s->Printf(", %sresolved, hit count = %u ",
                  (IsResolved() ? "" : "un"),
                  GetHitCount());
        if (m_options_ap.get())
        {
            m_options_ap->GetDescription (s, level);
        }
    }
}

void
BreakpointLocation::Dump(Stream *s) const
{
    if (s == NULL)
        return;

    s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64 "  load addr = 0x%8.8" PRIx64 "  state = %s  type = %s breakpoint  "
              "hw_index = %i  hit_count = %-4u  ignore_count = %-4u",
              GetID(),
              GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(),
              (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()),
              (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled",
              IsHardware() ? "hardware" : "software",
              GetHardwareIndex(),
              GetHitCount(),
              GetOptionsNoCreate()->GetIgnoreCount());
}

void
BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind)
{
    if (!m_being_created
        && !m_owner.IsInternal() 
        && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
    {
        Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, 
                                                                                     m_owner.shared_from_this());
        data->GetBreakpointLocationCollection().Add (shared_from_this());
        m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
    }
}
    
