//===-- 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/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},
    {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) && (stat_buf.st_mode & S_IFDIR))
                    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();
}

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().GetDemangledName());
                }
            }
        }
    }
    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();
}
