//===-- CommandCompletions.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
#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/Core/Module.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Variable.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},
    {eVariablePathCompletion,    CommandCompletions::VariablePath},
    {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...
    
    size_t 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)
{
    // Cache the full setting name list
    static StringList g_property_names;
    if (g_property_names.GetSize() == 0)
    {
        // Generate the full setting name list on demand
        lldb::OptionValuePropertiesSP properties_sp (interpreter.GetDebugger().GetValueProperties());
        if (properties_sp)
        {
            StreamString strm;
            properties_sp->DumpValue(NULL, strm, OptionValue::eDumpOptionName);
            const std::string &str = strm.GetString();
            g_property_names.SplitIntoLines(str.c_str(), str.size());
        }
    }
    
    size_t exact_matches_idx = SIZE_MAX;
    const size_t num_matches = g_property_names.AutoComplete (partial_setting_name, matches, exact_matches_idx);
    word_complete = exact_matches_idx != SIZE_MAX;
    return num_matches;
}


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


int
CommandCompletions::VariablePath (CommandInterpreter &interpreter,
                                  const char *partial_name,
                                  int match_start_point,
                                  int max_return_elements,
                                  SearchFilter *searcher,
                                  bool &word_complete,
                                  lldb_private::StringList &matches)
{
    return Variable::AutoComplete (interpreter.GetExecutionContext(), partial_name, matches, word_complete);
}


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 == ')' ||
        comp == '{' || comp == '}' ||
        comp == '+' ||
        comp == '.' ||
        comp == '*' ||
        comp == '|' ||
        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;
    if (completion_str && completion_str[0])
    {
        regex_str.append("^");
        regex_str.append(completion_str);
    }
    else
    {
        // Match anything since the completion string is empty
        regex_str.append(".");
    }
    std::string::iterator pos = find_if(regex_str.begin() + 1, regex_str.end(), regex_chars);
    while (pos < regex_str.end())
    {
        pos = regex_str.insert(pos, '\\');
        pos = find_if(pos + 2, 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 include_inlines = true;
        const bool append = true;
        context.module_sp->FindFunctions (m_regex, include_symbols, include_inlines, 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))
            {
                ConstString func_name = sc.GetFunctionName(Mangled::ePreferDemangled);
                if (!func_name.IsEmpty())
                    m_match_set.insert (func_name);
            }
        }
    }
    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)
    {
        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();
}
