//===-- 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,
    bool check_for_resolver
) :
    StoppointLocation (loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware),
    m_being_created(true),
    m_should_resolve_indirect_functions (false),
    m_is_reexported (false),
    m_is_indirect (false),
    m_address (addr),
    m_owner (owner),
    m_options_ap (),
    m_bp_site_sp (),
    m_condition_mutex ()
{
    if (check_for_resolver)
    {
        Symbol *symbol = m_address.CalculateSymbolContextSymbol();
        if (symbol && symbol->IsIndirect())
        {
            SetShouldResolveIndirectFunctions (true);
        }
    }
    
    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,
                                         false))
        {
            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;
    
    EvaluateExpressionOptions options;
    options.SetUnwindOnError(true);
    options.SetIgnoreBreakpoints(true);
    options.SetTryAllThreads(true);
    
    Error expr_error;
    
    StreamString execution_errors;
    
    ClangExpressionVariableSP result_variable_sp;
    
    ExpressionResults result_code =
    m_user_expression_sp->Execute(execution_errors,
                                  exe_ctx,
                                  options,
                                  m_user_expression_sp,
                                  result_variable_sp);
    
    bool ret;
    
    if (result_code == eExpressionCompleted)
    {
        if (!result_variable_sp)
        {
            error.SetErrorString("Expression did not return a result");
            return false;
        }
        
        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;

    lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), m_owner.IsHardware());

    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())
    {
        ProcessSP process_sp(m_owner.GetTarget().GetProcessSP());
        // If the process exists, get it to remove the owner, it will remove the physical implementation
        // of the breakpoint as well if there are no more owners.  Otherwise just remove this owner.
        if (process_sp)
            process_sp->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(),
                                                                           GetID(), m_bp_site_sp);
        else
            m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID());
        
        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)
        {
            if (IsReExported())
                s->PutCString ("re-exported target = ");
            else
                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();
                    if (IsReExported())
                        s->Indent ("re-exported target = ");
                    else
                        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 (level == eDescriptionLevelInitial)
        m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
    else
        m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
    
    if (IsIndirect() && m_bp_site_sp)
    {
        Address resolved_address;
        resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
        Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
        if (resolved_symbol)
        {
            if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
                s->Printf (", ");
            else if (level == lldb::eDescriptionLevelVerbose)
            {
                s->EOL();
                s->Indent();
            }
            s->Printf ("indirect target = %s", resolved_symbol->GetName().GetCString());
        }
    }

    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);
    }
}
    
