//===-- 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>
#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/Interpreter/OptionValueProperties.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/CleanUp.h"

#include "llvm/ADT/SmallString.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();
        SearchFilterForUnconstrainedSearches null_searcher (target_sp);
        completer.DoCompletion (&null_searcher);
    }
    else
    {
        completer.DoCompletion (searcher);
    }
    return matches.GetSize();
}

typedef struct DiskFilesOrDirectoriesBaton
{
    const char *remainder;
    char *partial_name_copy;
    bool only_directories;
    bool *saw_directory;
    StringList *matches;
    char *end_ptr;
    size_t baselen;
} DiskFilesOrDirectoriesBaton;

FileSpec::EnumerateDirectoryResult DiskFilesOrDirectoriesCallback(void *baton, FileSpec::FileType file_type, const FileSpec &spec)
{
    const char *name = spec.GetFilename().AsCString();

    const DiskFilesOrDirectoriesBaton *parameters = (DiskFilesOrDirectoriesBaton*)baton;
    char *end_ptr = parameters->end_ptr;
    char *partial_name_copy = parameters->partial_name_copy;
    const char *remainder = parameters->remainder;

    // Omit ".", ".." and any . files if the match string doesn't start with .
    if (name[0] == '.')
    {
        if (name[1] == '\0')
            return FileSpec::eEnumerateDirectoryResultNext;
        else if (name[1] == '.' && name[2] == '\0')
            return FileSpec::eEnumerateDirectoryResultNext;
        else if (remainder[0] != '.')
            return FileSpec::eEnumerateDirectoryResultNext;
    }

    // If we found a directory, we put a "/" at the end of the name.

    if (remainder[0] == '\0' || strstr(name, remainder) == name)
    {
        if (strlen(name) + parameters->baselen >= PATH_MAX)
            return FileSpec::eEnumerateDirectoryResultNext;

        strcpy(end_ptr, name);

        bool isa_directory = false;
        if (file_type == FileSpec::eFileTypeDirectory)
            isa_directory = true;
        else if (file_type == FileSpec::eFileTypeSymbolicLink)
        {
            struct stat stat_buf;
            if ((stat(partial_name_copy, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode))
                isa_directory = true;
        }

        if (isa_directory)
        {
            *parameters->saw_directory = true;
            size_t len = strlen(parameters->partial_name_copy);
            partial_name_copy[len] = '/';
            partial_name_copy[len + 1] = '\0';
        }
        if (parameters->only_directories && !isa_directory)
            return FileSpec::eEnumerateDirectoryResultNext;
        parameters->matches->AppendString(partial_name_copy);
    }

    return FileSpec::eEnumerateDirectoryResultNext;
}

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
    llvm::SmallString<64> containing_part;
    
    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.
            llvm::SmallString<64> resolved_username(partial_name_copy);
            FileSpec::ResolveUsername (resolved_username);
                                                          
           // Not sure how this would happen, a username longer than PATH_MAX?  Still...
            if (resolved_username.size() == 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 = ".";
            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 = "/";
        }
        else
        {
            containing_part.append(partial_name_copy, end_ptr);
        }
        // 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 == '~')
    {
        FileSpec::ResolveUsername(containing_part);
        // User name doesn't exist, we're not getting any further...
        if (containing_part.empty())
            return matches.GetSize();
    }

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

    size_t baselen = end_ptr - partial_name_copy;
    
    DiskFilesOrDirectoriesBaton parameters;
    parameters.remainder = remainder;
    parameters.partial_name_copy = partial_name_copy;
    parameters.only_directories = only_directories;
    parameters.saw_directory = &saw_directory;
    parameters.matches = &matches;
    parameters.end_ptr = end_ptr;
    parameters.baselen = baselen;

    FileSpec::EnumerateDirectory(containing_part.c_str(), true, true, true, DiskFilesOrDirectoriesCallback, &parameters);
    
    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();
        SearchFilterForUnconstrainedSearches 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();
        SearchFilterForUnconstrainedSearches 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();
}
