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

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

#include "lldb/lldb-private.h"
#include "lldb/Core/SearchFilter.h"
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// SearchFilter constructor
//----------------------------------------------------------------------
Searcher::Searcher ()
{

}

Searcher::~Searcher ()
{

}

void
Searcher::GetDescription (Stream *s)
{
}

//----------------------------------------------------------------------
// SearchFilter constructor
//----------------------------------------------------------------------
SearchFilter::SearchFilter(lldb::TargetSP &target_sp) :
    m_target_sp (target_sp)
{
}

//----------------------------------------------------------------------
// SearchFilter copy constructor
//----------------------------------------------------------------------
SearchFilter::SearchFilter(const SearchFilter& rhs) :
    m_target_sp (rhs.m_target_sp)
{
}

//----------------------------------------------------------------------
// SearchFilter assignment operator
//----------------------------------------------------------------------
const SearchFilter&
SearchFilter::operator=(const SearchFilter& rhs)
{
    m_target_sp = rhs.m_target_sp;
    return *this;
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
SearchFilter::~SearchFilter()
{
}

bool
SearchFilter::ModulePasses (const FileSpec &spec)
{
    return true;
}

bool
SearchFilter::ModulePasses (const ModuleSP &module_sp)
{
    return true;
}

bool
SearchFilter::SymbolContextPasses
(
    const SymbolContext &context,
    lldb::SymbolContextItem scope
)
{
    return true;
}

bool
SearchFilter::AddressPasses (Address &address)
{
    return true;
}

bool
SearchFilter::CompUnitPasses (FileSpec &fileSpec)
{
    return true;
}

bool
SearchFilter::CompUnitPasses (CompileUnit &compUnit)
{
    return true;
}

void
SearchFilter::GetDescription (Stream *s)
{
}

void
SearchFilter::Dump (Stream *s) const
{

}

//----------------------------------------------------------------------
// UTILITY Functions to help iterate down through the elements of the
// SymbolContext.
//----------------------------------------------------------------------

void
SearchFilter::Search (Searcher &searcher)
{
    SymbolContext empty_sc;

    if (m_target_sp == NULL)
        return;
    empty_sc.target_sp = m_target_sp;

    if (searcher.GetDepth() == Searcher::eDepthTarget)
        searcher.SearchCallback (*this, empty_sc, NULL, false);
    else
        DoModuleIteration(empty_sc, searcher);
}

void
SearchFilter::SearchInModuleList (Searcher &searcher, ModuleList &modules)
{
    SymbolContext empty_sc;

    if (m_target_sp == NULL)
        return;
    empty_sc.target_sp = m_target_sp;

    if (searcher.GetDepth() == Searcher::eDepthTarget)
        searcher.SearchCallback (*this, empty_sc, NULL, false);
    else
    {
        const size_t numModules = modules.GetSize();

        for (size_t i = 0; i < numModules; i++)
        {
            ModuleSP module_sp(modules.GetModuleAtIndex(i));
            if (ModulePasses(module_sp))
            {
                if (DoModuleIteration(module_sp, searcher) == Searcher::eCallbackReturnStop)
                    return;
            }
        }
    }
}


Searcher::CallbackReturn
SearchFilter::DoModuleIteration (const lldb::ModuleSP& module_sp, Searcher &searcher)
{
    SymbolContext matchingContext (m_target_sp, module_sp);
    return DoModuleIteration(matchingContext, searcher);
}

Searcher::CallbackReturn
SearchFilter::DoModuleIteration (const SymbolContext &context, Searcher &searcher)
{
    Searcher::CallbackReturn shouldContinue;

    if (searcher.GetDepth () >= Searcher::eDepthModule)
    {
        if (!context.module_sp)
        {
            size_t n_modules = m_target_sp->GetImages().GetSize();
            for (size_t i = 0; i < n_modules; i++)
            {
                // If this is the last level supplied, then call the callback directly,
                // otherwise descend.
                ModuleSP module_sp(m_target_sp->GetImages().GetModuleAtIndex(i));
                if (!ModulePasses (module_sp))
                    continue;

                if (searcher.GetDepth () == Searcher::eDepthModule)
                {
                    SymbolContext matchingContext(m_target_sp, module_sp);

                    shouldContinue = searcher.SearchCallback (*this, matchingContext, NULL, false);
                    if (shouldContinue == Searcher::eCallbackReturnStop
                        || shouldContinue == Searcher::eCallbackReturnPop)
                        return shouldContinue;
                }
                else
                {
                    shouldContinue = DoCUIteration(module_sp, context, searcher);
                    if (shouldContinue == Searcher::eCallbackReturnStop)
                        return shouldContinue;
                    else if (shouldContinue == Searcher::eCallbackReturnPop)
                        continue;
                }
            }
        }
        else
        {
            if (searcher.GetDepth () == Searcher::eDepthModule)
            {
                SymbolContext matchingContext(context.module_sp.get());

                shouldContinue = searcher.SearchCallback (*this, matchingContext, NULL, false);
            }
            else
            {
                return DoCUIteration(context.module_sp, context, searcher);
            }
        }

    }
    return Searcher::eCallbackReturnContinue;
}

Searcher::CallbackReturn
SearchFilter::DoCUIteration (const ModuleSP &module_sp, const SymbolContext &context, Searcher &searcher)
{
    Searcher::CallbackReturn shouldContinue;
    if (context.comp_unit == NULL)
    {
        uint32_t num_comp_units = module_sp->GetNumCompileUnits();
        for (uint32_t i = 0; i < num_comp_units; i++)
        {
            CompUnitSP cu_sp (module_sp->GetCompileUnitAtIndex (i));
            if (!CompUnitPasses (*(cu_sp.get())))
                continue;

            if (searcher.GetDepth () == Searcher::eDepthCompUnit)
            {
                SymbolContext matchingContext(m_target_sp, module_sp, cu_sp.get());

                shouldContinue = searcher.SearchCallback (*this, matchingContext, NULL, false);

                if (shouldContinue == Searcher::eCallbackReturnPop)
                    return Searcher::eCallbackReturnContinue;
                else if (shouldContinue == Searcher::eCallbackReturnStop)
                    return shouldContinue;
            }
            else
            {
                // FIXME Descend to block.
            }

        }
    }
    else
    {
        if (CompUnitPasses(*context.comp_unit))
        {
            SymbolContext matchingContext (m_target_sp, module_sp, context.comp_unit);
            return searcher.SearchCallback (*this, matchingContext, NULL, false);
        }
    }
    return Searcher::eCallbackReturnContinue;
}

Searcher::CallbackReturn
SearchFilter::DoFunctionIteration (Function *function, const SymbolContext &context, Searcher &searcher)
{
    // FIXME: Implement...
    return Searcher::eCallbackReturnContinue;
}

//----------------------------------------------------------------------
//  SearchFilterByModule:
//  Selects a shared library matching a given file spec
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// SearchFilterByModule constructors
//----------------------------------------------------------------------

SearchFilterByModule::SearchFilterByModule (lldb::TargetSP &target_sp, const FileSpec &module) :
    SearchFilter (target_sp),
    m_module_spec (module)
{
}


//----------------------------------------------------------------------
// SearchFilterByModule copy constructor
//----------------------------------------------------------------------
SearchFilterByModule::SearchFilterByModule(const SearchFilterByModule& rhs) :
    SearchFilter (rhs),
    m_module_spec (rhs.m_module_spec)
{
}

//----------------------------------------------------------------------
// SearchFilterByModule assignment operator
//----------------------------------------------------------------------
const SearchFilterByModule&
SearchFilterByModule::operator=(const SearchFilterByModule& rhs)
{
    m_target_sp = rhs.m_target_sp;
    m_module_spec = rhs.m_module_spec;
    return *this;
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
SearchFilterByModule::~SearchFilterByModule()
{
}

bool
SearchFilterByModule::ModulePasses (const ModuleSP &module_sp)
{
    if (module_sp && FileSpec::Compare (module_sp->GetFileSpec(), m_module_spec, false) == 0)
        return true;
    else
        return false;
}

bool
SearchFilterByModule::ModulePasses (const FileSpec &spec)
{
    if (FileSpec::Compare(spec, m_module_spec, false) == 0)
        return true;
    else
        return false;
}

bool
SearchFilterByModule::SymbolContextPasses
(
 const SymbolContext &context,
 lldb::SymbolContextItem scope
 )
{
    if (!(scope & eSymbolContextModule))
        return false;

    if (context.module_sp && FileSpec::Compare (context.module_sp->GetFileSpec(), m_module_spec, false) == 0)
        return true;
    else
        return false;
}

bool
SearchFilterByModule::AddressPasses (Address &address)
{
    // FIXME: Not yet implemented
    return true;
}


bool
SearchFilterByModule::CompUnitPasses (FileSpec &fileSpec)
{
    return true;
}

bool
SearchFilterByModule::CompUnitPasses (CompileUnit &compUnit)
{
    return true;
}

void
SearchFilterByModule::Search (Searcher &searcher)
{
    if (!m_target_sp)
        return;

    if (searcher.GetDepth() == Searcher::eDepthTarget)
    {
        SymbolContext empty_sc;
        empty_sc.target_sp = m_target_sp;
        searcher.SearchCallback (*this, empty_sc, NULL, false);
    }

    // If the module file spec is a full path, then we can just find the one
    // filespec that passes.  Otherwise, we need to go through all modules and
    // find the ones that match the file name.

    ModuleList matching_modules;
    const size_t num_modules = m_target_sp->GetImages().GetSize ();
    for (size_t i = 0; i < num_modules; i++)
    {
        Module* module = m_target_sp->GetImages().GetModulePointerAtIndex(i);
        if (FileSpec::Compare (m_module_spec, module->GetFileSpec(), false) == 0)
        {
            SymbolContext matchingContext(m_target_sp, module->GetSP());
            Searcher::CallbackReturn shouldContinue;

            shouldContinue = DoModuleIteration(matchingContext, searcher);
            if (shouldContinue == Searcher::eCallbackReturnStop)
                return;
        }
    }
}

void
SearchFilterByModule::GetDescription (Stream *s)
{
    s->PutCString(", module = ");
    if (s->GetVerbose())
    {
        char buffer[2048];
        m_module_spec.GetPath(buffer, 2047);
        s->PutCString(buffer);
    }
    else
    {
        s->PutCString(m_module_spec.GetFilename().AsCString("<unknown>"));
    }
}

void
SearchFilterByModule::Dump (Stream *s) const
{

}
