//===-- CommandCompletions.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
#include <sys/stat.h>
#include <dirent.h>
#if defined(__APPLE__) || defined(__linux__)
#include <pwd.h>
#endif

// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Host/FileSpec.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/CleanUp.h"

using namespace lldb_private;

CommandCompletions::CommonCompletionElement
CommandCompletions::g_common_completions[] =
{
    {eCustomCompletion,          NULL},
    {eSourceFileCompletion,      CommandCompletions::SourceFiles},
    {eDiskFileCompletion,        CommandCompletions::DiskFiles},
    {eDiskDirectoryCompletion,   CommandCompletions::DiskDirectories},
    {eSymbolCompletion,          CommandCompletions::Symbols},
    {eModuleCompletion,          CommandCompletions::Modules},
    {eSettingsNameCompletion,    CommandCompletions::SettingsNames},
    {ePlatformPluginCompletion,  CommandCompletions::PlatformPluginNames},
    {eArchitectureCompletion,    CommandCompletions::ArchitectureNames},
    {eNoCompletion,              NULL}      // This one has to be last in the list.
};

bool
CommandCompletions::InvokeCommonCompletionCallbacks 
(
    CommandInterpreter &interpreter,
    uint32_t completion_mask,
    const char *completion_str,
    int match_start_point,
    int max_return_elements,
    SearchFilter *searcher,
    bool &word_complete,
    StringList &matches
)
{
    bool handled = false;

    if (completion_mask & eCustomCompletion)
        return false;

    for (int i = 0; ; i++)
    {
        if (g_common_completions[i].type == eNoCompletion)
            break;
         else if ((g_common_completions[i].type & completion_mask) == g_common_completions[i].type
                   && g_common_completions[i].callback != NULL)
         {
            handled = true;
            g_common_completions[i].callback (interpreter,
                                              completion_str,
                                              match_start_point,
                                              max_return_elements,
                                              searcher,
                                              word_complete,
                                              matches);
        }
    }
    return handled;
}

int
CommandCompletions::SourceFiles 
(
    CommandInterpreter &interpreter,
    const char *partial_file_name,
    int match_start_point,
    int max_return_elements,
    SearchFilter *searcher,
    bool &word_complete,
    StringList &matches
)
{
    word_complete = true;
    // Find some way to switch "include support files..."
    SourceFileCompleter completer (interpreter,
                                   false, 
                                   partial_file_name, 
                                   match_start_point, 
                                   max_return_elements,
                                   matches);

    if (searcher == NULL)
    {
        lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
        SearchFilter null_searcher (target_sp);
        completer.DoCompletion (&null_searcher);
    }
    else
    {
        completer.DoCompletion (searcher);
    }
    return matches.GetSize();
}

static int
DiskFilesOrDirectories 
(
    const char *partial_file_name,
    bool only_directories,
    bool &saw_directory,
    StringList &matches
)
{
    // I'm going to  use the "glob" function with GLOB_TILDE for user directory expansion.  
    // If it is not defined on your host system, you'll need to implement it yourself...
    
    int partial_name_len = strlen(partial_file_name);
    
    if (partial_name_len >= PATH_MAX)
        return matches.GetSize();
    
    // This copy of the string will be cut up into the directory part, and the remainder.  end_ptr
    // below will point to the place of the remainder in this string.  Then when we've resolved the
    // containing directory, and opened it, we'll read the directory contents and overwrite the
    // partial_name_copy starting from end_ptr with each of the matches.  Thus we will preserve
    // the form the user originally typed.
    
    char partial_name_copy[PATH_MAX];
    memcpy(partial_name_copy, partial_file_name, partial_name_len);
    partial_name_copy[partial_name_len] = '\0';
    
    // We'll need to save a copy of the remainder for comparison, which we do here.
    char remainder[PATH_MAX];
    
    // end_ptr will point past the last / in partial_name_copy, or if there is no slash to the beginning of the string.
    char *end_ptr;
    
    end_ptr = strrchr(partial_name_copy, '/');
    
    // This will store the resolved form of the containing directory
    char containing_part[PATH_MAX];
    
    if (end_ptr == NULL)
    {
        // There's no directory.  If the thing begins with a "~" then this is a bare
        // user name.
        if (*partial_name_copy == '~')
        {
            // Nothing here but the user name.  We could just put a slash on the end, 
            // but for completeness sake we'll resolve the user name and only put a slash
            // on the end if it exists.
            char resolved_username[PATH_MAX];
            size_t resolved_username_len = FileSpec::ResolveUsername (partial_name_copy, resolved_username, 
                                                          sizeof (resolved_username));
                                                          
           // Not sure how this would happen, a username longer than PATH_MAX?  Still...
            if (resolved_username_len >= sizeof (resolved_username))
                return matches.GetSize();
            else if (resolved_username_len == 0)
            {
                // The user name didn't resolve, let's look in the password database for matches.
                // The user name database contains duplicates, and is not in alphabetical order, so
                // we'll use a set to manage that for us.
                FileSpec::ResolvePartialUsername (partial_name_copy, matches);
                if (matches.GetSize() > 0)
                    saw_directory = true;
                return matches.GetSize();
            } 
            else
            {   
                //The thing exists, put a '/' on the end, and return it...
                // FIXME: complete user names here:
                partial_name_copy[partial_name_len] = '/';
                partial_name_copy[partial_name_len+1] = '\0';
                matches.AppendString(partial_name_copy);
                saw_directory = true;
                return matches.GetSize();
            }
        }
        else
        {
            // The containing part is the CWD, and the whole string is the remainder.
            containing_part[0] = '.';
            containing_part[1] = '\0';
            strcpy(remainder, partial_name_copy);
            end_ptr = partial_name_copy;
        }
    }
    else
    {
        if (end_ptr == partial_name_copy)
        {
            // We're completing a file or directory in the root volume.
            containing_part[0] = '/';
            containing_part[1] = '\0';
        }
        else
        {
            size_t len = end_ptr - partial_name_copy;
            memcpy(containing_part, partial_name_copy, len);
            containing_part[len] = '\0';
        }
        // Push end_ptr past the final "/" and set remainder.
        end_ptr++;
        strcpy(remainder, end_ptr);
    }
    
    // Look for a user name in the containing part, and if it's there, resolve it and stick the
    // result back into the containing_part:

    if (*partial_name_copy == '~')
    {
        size_t resolved_username_len = FileSpec::ResolveUsername(containing_part, 
                                                                 containing_part, 
                                                                 sizeof (containing_part));
        // User name doesn't exist, we're not getting any further...
        if (resolved_username_len == 0 || resolved_username_len >= sizeof (containing_part))
            return matches.GetSize();
    }

    // Okay, containing_part is now the directory we want to open and look for files:

    lldb_utility::CleanUp <DIR *, int> dir_stream (opendir(containing_part), NULL, closedir);
    if (!dir_stream.is_valid())
        return matches.GetSize();
    
    struct dirent *dirent_buf;
    
    size_t baselen = end_ptr - partial_name_copy;
    
    while ((dirent_buf = readdir(dir_stream.get())) != NULL) 
    {
        char *name = dirent_buf->d_name;
        
        // Omit ".", ".." and any . files if the match string doesn't start with .
        if (name[0] == '.')
        {
            if (name[1] == '\0')
                continue;
            else if (name[1] == '.' && name[2] == '\0')
                continue;
            else if (remainder[0] != '.')
                continue;
        }
        
        // If we found a directory, we put a "/" at the end of the name.
        
        if (remainder[0] == '\0' || strstr(dirent_buf->d_name, remainder) == name)
        {
            if (strlen(name) + baselen >= PATH_MAX)
                continue;
                
            strcpy(end_ptr, name);
            
            bool isa_directory = false;
            if (dirent_buf->d_type & DT_DIR)
                isa_directory = true;
            else if (dirent_buf->d_type & DT_LNK)
            { 
                struct stat stat_buf;
                if ((stat(partial_name_copy, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode))
                    isa_directory = true;
            }
            
            if (isa_directory)
            {
                saw_directory = true;
                size_t len = strlen(partial_name_copy);
                partial_name_copy[len] = '/';
                partial_name_copy[len + 1] = '\0';
            }
            if (only_directories && !isa_directory)
                continue;
            matches.AppendString(partial_name_copy);
        }
    }
    
    return matches.GetSize();
}

int
CommandCompletions::DiskFiles 
(
    CommandInterpreter &interpreter,
    const char *partial_file_name,
    int match_start_point,
    int max_return_elements,
    SearchFilter *searcher,
    bool &word_complete,
    StringList &matches
)
{

    int ret_val = DiskFilesOrDirectories (partial_file_name,
                                          false,
                                          word_complete,
                                          matches);
    word_complete = !word_complete;
    return ret_val;
}

int
CommandCompletions::DiskDirectories 
(
    CommandInterpreter &interpreter,
    const char *partial_file_name,
    int match_start_point,
    int max_return_elements,
    SearchFilter *searcher,
    bool &word_complete,
    StringList &matches
)
{
    int ret_val =  DiskFilesOrDirectories (partial_file_name,
                                           true,
                                           word_complete,
                                           matches); 
    word_complete = false;
    return ret_val;
}

int
CommandCompletions::Modules 
(
    CommandInterpreter &interpreter,
    const char *partial_file_name,
    int match_start_point,
    int max_return_elements,
    SearchFilter *searcher,
    bool &word_complete,
    StringList &matches
)
{
    word_complete = true;
    ModuleCompleter completer (interpreter,
                               partial_file_name, 
                               match_start_point, 
                               max_return_elements, 
                               matches);
    
    if (searcher == NULL)
    {
        lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
        SearchFilter null_searcher (target_sp);
        completer.DoCompletion (&null_searcher);
    }
    else
    {
        completer.DoCompletion (searcher);
    }
    return matches.GetSize();
}

int
CommandCompletions::Symbols 
(
    CommandInterpreter &interpreter,
    const char *partial_file_name,
    int match_start_point,
    int max_return_elements,
    SearchFilter *searcher,
    bool &word_complete,
    StringList &matches)
{
    word_complete = true;
    SymbolCompleter completer (interpreter,
                               partial_file_name, 
                               match_start_point, 
                               max_return_elements, 
                               matches);

    if (searcher == NULL)
    {
        lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
        SearchFilter null_searcher (target_sp);
        completer.DoCompletion (&null_searcher);
    }
    else
    {
        completer.DoCompletion (searcher);
    }
    return matches.GetSize();
}

int
CommandCompletions::SettingsNames (CommandInterpreter &interpreter,
                                   const char *partial_setting_name,
                                   int match_start_point,
                                   int max_return_elements,
                                   SearchFilter *searcher,
                                   bool &word_complete,
                                   StringList &matches)
{
    lldb::UserSettingsControllerSP root_settings = Debugger::GetSettingsController();
    Args partial_setting_name_pieces = UserSettingsController::BreakNameIntoPieces (partial_setting_name);

    return UserSettingsController::CompleteSettingsNames (root_settings,
                                                          partial_setting_name_pieces,
                                                          word_complete,
                                                          matches);

    //return matches.GetSize();
}


int
CommandCompletions::PlatformPluginNames (CommandInterpreter &interpreter,
                                         const char *partial_name,
                                         int match_start_point,
                                         int max_return_elements,
                                         SearchFilter *searcher,
                                         bool &word_complete,
                                         lldb_private::StringList &matches)
{
    const uint32_t num_matches = PluginManager::AutoCompletePlatformName(partial_name, matches);
    word_complete = num_matches == 1;
    return num_matches;
}

int
CommandCompletions::ArchitectureNames (CommandInterpreter &interpreter,
                                       const char *partial_name,
                                       int match_start_point,
                                       int max_return_elements,
                                       SearchFilter *searcher,
                                       bool &word_complete,
                                       lldb_private::StringList &matches)
{
    const uint32_t num_matches = ArchSpec::AutoComplete (partial_name, matches);
    word_complete = num_matches == 1;
    return num_matches;
}


CommandCompletions::Completer::Completer 
(
    CommandInterpreter &interpreter,
    const char *completion_str,
    int match_start_point,
    int max_return_elements,
    StringList &matches
) :
    m_interpreter (interpreter),
    m_completion_str (completion_str),
    m_match_start_point (match_start_point),
    m_max_return_elements (max_return_elements),
    m_matches (matches)
{
}

CommandCompletions::Completer::~Completer ()
{

}

//----------------------------------------------------------------------
// SourceFileCompleter
//----------------------------------------------------------------------

CommandCompletions::SourceFileCompleter::SourceFileCompleter 
(
    CommandInterpreter &interpreter,
    bool include_support_files,
    const char *completion_str,
    int match_start_point,
    int max_return_elements,
    StringList &matches
) :
    CommandCompletions::Completer (interpreter, completion_str, match_start_point, max_return_elements, matches),
    m_include_support_files (include_support_files),
    m_matching_files()
{
    FileSpec partial_spec (m_completion_str.c_str(), false);
    m_file_name = partial_spec.GetFilename().GetCString();
    m_dir_name = partial_spec.GetDirectory().GetCString();
}

Searcher::Depth
CommandCompletions::SourceFileCompleter::GetDepth()
{
    return eDepthCompUnit;
}

Searcher::CallbackReturn
CommandCompletions::SourceFileCompleter::SearchCallback (
    SearchFilter &filter,
    SymbolContext &context,
    Address *addr,
    bool complete
)
{
    if (context.comp_unit != NULL)
    {
        if (m_include_support_files)
        {
            FileSpecList supporting_files = context.comp_unit->GetSupportFiles();
            for (size_t sfiles = 0; sfiles < supporting_files.GetSize(); sfiles++)
            {
                const FileSpec &sfile_spec = supporting_files.GetFileSpecAtIndex(sfiles);
                const char *sfile_file_name = sfile_spec.GetFilename().GetCString();
                const char *sfile_dir_name = sfile_spec.GetFilename().GetCString();
                bool match = false;
                if (m_file_name && sfile_file_name
                    && strstr (sfile_file_name, m_file_name) == sfile_file_name)
                    match = true;
                if (match && m_dir_name && sfile_dir_name
                    && strstr (sfile_dir_name, m_dir_name) != sfile_dir_name)
                    match = false;

                if (match)
                {
                    m_matching_files.AppendIfUnique(sfile_spec);
                }
            }

        }
        else
        {
            const char *cur_file_name = context.comp_unit->GetFilename().GetCString();
            const char *cur_dir_name = context.comp_unit->GetDirectory().GetCString();

            bool match = false;
            if (m_file_name && cur_file_name
                && strstr (cur_file_name, m_file_name) == cur_file_name)
                match = true;

            if (match && m_dir_name && cur_dir_name
                && strstr (cur_dir_name, m_dir_name) != cur_dir_name)
                match = false;

            if (match)
            {
                m_matching_files.AppendIfUnique(context.comp_unit);
            }
        }
    }
    return Searcher::eCallbackReturnContinue;
}

size_t
CommandCompletions::SourceFileCompleter::DoCompletion (SearchFilter *filter)
{
    filter->Search (*this);
    // Now convert the filelist to completions:
    for (size_t i = 0; i < m_matching_files.GetSize(); i++)
    {
        m_matches.AppendString (m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString());
    }
    return m_matches.GetSize();

}

//----------------------------------------------------------------------
// SymbolCompleter
//----------------------------------------------------------------------

static bool
regex_chars (const char comp)
{
    if (comp == '[' || comp == ']' || comp == '(' || comp == ')')
        return true;
    else
        return false;
}
CommandCompletions::SymbolCompleter::SymbolCompleter 
(
    CommandInterpreter &interpreter,
    const char *completion_str,
    int match_start_point,
    int max_return_elements,
    StringList &matches
) :
    CommandCompletions::Completer (interpreter, completion_str, match_start_point, max_return_elements, matches)
{
    std::string regex_str ("^");
    regex_str.append(completion_str);
    regex_str.append(".*");
    std::string::iterator pos;

    pos = find_if(regex_str.begin(), regex_str.end(), regex_chars);
    while (pos < regex_str.end()) {
        pos = regex_str.insert(pos, '\\');
        pos += 2;
        pos = find_if(pos, regex_str.end(), regex_chars);
    }
    m_regex.Compile(regex_str.c_str());
}

Searcher::Depth
CommandCompletions::SymbolCompleter::GetDepth()
{
    return eDepthModule;
}

Searcher::CallbackReturn
CommandCompletions::SymbolCompleter::SearchCallback (
    SearchFilter &filter,
    SymbolContext &context,
    Address *addr,
    bool complete
)
{
    if (context.module_sp)
    {
        SymbolContextList sc_list;        
        const bool include_symbols = true;
        const bool append = true;
        context.module_sp->FindFunctions (m_regex, include_symbols, append, sc_list);

        SymbolContext sc;
        // Now add the functions & symbols to the list - only add if unique:
        for (uint32_t i = 0; i < sc_list.GetSize(); i++)
        {
            if (sc_list.GetContextAtIndex(i, sc))
            {
                if (sc.function)
                {
                    m_match_set.insert (sc.function->GetMangled().GetDemangledName());
                }
                else if (sc.symbol && sc.symbol->GetAddressRangePtr())
                {
                    m_match_set.insert (sc.symbol->GetMangled().GetName());
                }
            }
        }
    }
    return Searcher::eCallbackReturnContinue;
}

size_t
CommandCompletions::SymbolCompleter::DoCompletion (SearchFilter *filter)
{
    filter->Search (*this);
    collection::iterator pos = m_match_set.begin(), end = m_match_set.end();
    for (pos = m_match_set.begin(); pos != end; pos++)
        m_matches.AppendString((*pos).GetCString());

    return m_matches.GetSize();
}

//----------------------------------------------------------------------
// ModuleCompleter
//----------------------------------------------------------------------
CommandCompletions::ModuleCompleter::ModuleCompleter 
(
    CommandInterpreter &interpreter,
    const char *completion_str,
    int match_start_point,
    int max_return_elements,
    StringList &matches
) :
    CommandCompletions::Completer (interpreter, completion_str, match_start_point, max_return_elements, matches)
{
    FileSpec partial_spec (m_completion_str.c_str(), false);
    m_file_name = partial_spec.GetFilename().GetCString();
    m_dir_name = partial_spec.GetDirectory().GetCString();
}

Searcher::Depth
CommandCompletions::ModuleCompleter::GetDepth()
{
    return eDepthModule;
}

Searcher::CallbackReturn
CommandCompletions::ModuleCompleter::SearchCallback (
    SearchFilter &filter,
    SymbolContext &context,
    Address *addr,
    bool complete
)
{
    if (context.module_sp != NULL)
    {
        const char *cur_file_name = context.module_sp->GetFileSpec().GetFilename().GetCString();
        const char *cur_dir_name = context.module_sp->GetFileSpec().GetDirectory().GetCString();

        bool match = false;
        if (m_file_name && cur_file_name
            && strstr (cur_file_name, m_file_name) == cur_file_name)
            match = true;

        if (match && m_dir_name && cur_dir_name
            && strstr (cur_dir_name, m_dir_name) != cur_dir_name)
            match = false;

        if (match)
        {
            m_matches.AppendString (cur_file_name);
        }
    }
    return Searcher::eCallbackReturnContinue;
}

size_t
CommandCompletions::ModuleCompleter::DoCompletion (SearchFilter *filter)
{
    filter->Search (*this);
    return m_matches.GetSize();
}
