//===-- ThreadPlanTestCondition.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/ThreadPlanTestCondition.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes

#include "lldb/lldb-private-log.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Thread.h"

using namespace lldb;
using namespace lldb_private;


//----------------------------------------------------------------------
// ThreadPlanTestCondition: Step through a stack range, either stepping over or into
// based on the value of \a type.
//----------------------------------------------------------------------

ThreadPlanTestCondition::ThreadPlanTestCondition (Thread& thread,
                                                  ExecutionContext &exe_ctx, 
                                                  ClangUserExpression *expression, 
                                                  const BreakpointLocationSP &break_loc_sp, 
                                                  bool stop_others) :
    ThreadPlan (ThreadPlan::eKindTestCondition, "test condition", thread, eVoteNoOpinion, eVoteNoOpinion),
    m_expression (expression),
    m_exe_ctx (exe_ctx),
    m_break_loc_sp (break_loc_sp),
    m_did_stop (false),
    m_stop_others (stop_others)
{
}

ThreadPlanTestCondition::~ThreadPlanTestCondition ()
{
}

bool
ThreadPlanTestCondition::ValidatePlan (Stream *error)
{
    return true;
}

void 
ThreadPlanTestCondition::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
    if (m_expression)
        s->Printf("Thread plan to test condition: \"%s\".", m_expression->GetUserText());
    else
        s->Printf("Thread plan to test unspecified condition.");
}

bool 
ThreadPlanTestCondition::ShouldStop (Event *event_ptr)
{    
    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
    if (m_thread.IsThreadPlanDone(m_expression_plan_sp.get()))
    {
        lldb::ClangExpressionVariableSP expr_result;
        StreamString error_stream;
        m_expression->FinalizeJITExecution(error_stream, m_exe_ctx, expr_result);
        
        ValueObjectSP result_sp (expr_result->GetValueObject());
        if (result_sp)
        {
            // FIXME: This is not the right answer, we should have a "GetValueAsBoolean..."
            Scalar scalar_value;
            if (result_sp->ResolveValue (scalar_value))
            {
                if (scalar_value.ULongLong(1) == 0)
                    m_did_stop = false;
                else
                    m_did_stop = true;
            }
            if (log)
                log->Printf("Condition successfully evaluated, result is %s.\n", m_did_stop ? "true" : "false");
        }
        else
        {
            if (log)
                log->Printf("Failed to get a result from the expression, error: \"%s\"\n", error_stream.GetData());
            m_did_stop = true;
        }
    }
    else if (m_exe_ctx.GetThreadRef().WasThreadPlanDiscarded (m_expression_plan_sp.get()))
    {
        if (log)
            log->Printf("ExecuteExpression thread plan was discarded.\n");
        m_did_stop = true; 
    }
    
    // One tricky bit, somebody might have disabled/deleted the breakpoint while we were running this condition, if so we
    // should just continue.  If the breakpoint gets disabled, then its "site" will be null'ed out, so we can't report
    // this as a breakpoint event any more, since we can't reconstruct it's site.  So just pass the event on.
    if (!m_break_loc_sp->IsEnabled())
    {
        m_did_stop = false;
    }
    else
    {
        // Now we have to change the event to a breakpoint event and mark it up appropriately:
        Process::ProcessEventData *new_data = new Process::ProcessEventData (m_thread.GetProcess().shared_from_this(), eStateStopped);
        event_ptr->SetData(new_data);
        event_ptr->SetType(Process::eBroadcastBitStateChanged);
        SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID (m_thread, 
                                                                    m_break_loc_sp->GetBreakpointSite()->GetID(),
                                                                    m_did_stop));
        if (m_did_stop)
        {
            Process::ProcessEventData::SetRestartedInEvent (event_ptr, false);
        }
        else
        {
            Process::ProcessEventData::SetRestartedInEvent (event_ptr, true);
        }
    }
    SetPlanComplete();
    return m_did_stop;
}

bool
ThreadPlanTestCondition::PlanExplainsStop ()
{
    // We explain all stops, and we just can the execution and return true if we stop for any
    // reason other than that our expression execution is done.
    return true;
}

Vote
ThreadPlanTestCondition::ShouldReportStop (Event *event_ptr)
{
    if (m_did_stop)
    {
        return eVoteYes;
    }
    else 
    {
        return eVoteNo;
    }
}

void
ThreadPlanTestCondition::DidPush()
{
    StreamString error_stream;
    m_expression_plan_sp.reset(m_expression->GetThreadPlanToExecuteJITExpression (error_stream, m_exe_ctx));
    m_thread.QueueThreadPlan (m_expression_plan_sp, false);
}

bool
ThreadPlanTestCondition::StopOthers ()
{
    return m_stop_others;
}

bool
ThreadPlanTestCondition::WillStop ()
{
    return true;
}

StateType
ThreadPlanTestCondition::GetPlanRunState ()
{
    return eStateRunning;
}

bool
ThreadPlanTestCondition::MischiefManaged ()
{
    // If we get a stop we're done, we don't puase in the middle of 
    // condition execution.
    return true;
}
