//===-- Symbols.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/Host/Symbols.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
#include "lldb/Core/UUID.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/SafeMachO.h"

#include "llvm/Support/FileSystem.h"

// From MacOSX system header "mach/machine.h"
typedef int cpu_type_t;
typedef int cpu_subtype_t;

using namespace lldb;
using namespace lldb_private;
using namespace llvm::MachO;

#if defined(__APPLE__)

// Forward declaration of method defined in source/Host/macosx/Symbols.cpp
int
LocateMacOSXFilesUsingDebugSymbols
(
    const ModuleSpec &module_spec,
    ModuleSpec &return_module_spec
);

#else

int
LocateMacOSXFilesUsingDebugSymbols
(
    const ModuleSpec &module_spec,
    ModuleSpec &return_module_spec
) {
    // Cannot find MacOSX files using debug symbols on non MacOSX.
    return 0;
}

#endif

static bool
FileAtPathContainsArchAndUUID (const FileSpec &file_fspec, const ArchSpec *arch, const lldb_private::UUID *uuid)
{
    ModuleSpecList module_specs;
    if (ObjectFile::GetModuleSpecifications(file_fspec, 0, 0, module_specs))
    {
        ModuleSpec spec;
        for (size_t i = 0; i < module_specs.GetSize(); ++i)
        {
            assert(module_specs.GetModuleSpecAtIndex(i, spec));
            if ((uuid == NULL || (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
                (arch == NULL || (spec.GetArchitecturePtr() && spec.GetArchitecture().IsCompatibleMatch(*arch))))
            {
                return true;
            }
        }
    }
    return false;
}

static bool
LocateDSYMInVincinityOfExecutable (const ModuleSpec &module_spec, FileSpec &dsym_fspec)
{
    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
    if (exec_fspec)
    {
        char path[PATH_MAX];
        if (exec_fspec->GetPath(path, sizeof(path)))
        {
            // Make sure the module isn't already just a dSYM file...
            if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL)
            {
                if (log)
                {
                    if (module_spec.GetUUIDPtr() && module_spec.GetUUIDPtr()->IsValid())
                    {
                        log->Printf ("Searching for dSYM bundle next to executable %s, UUID %s", path, module_spec.GetUUIDPtr()->GetAsString().c_str());
                    }
                    else
                    {
                        log->Printf ("Searching for dSYM bundle next to executable %s", path);
                    }
                }
                size_t obj_file_path_length = strlen(path);
                ::strncat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path) - strlen(path) - 1);
                ::strncat(path, exec_fspec->GetFilename().AsCString(), sizeof(path) - strlen(path) - 1);

                dsym_fspec.SetFile(path, false);

                ModuleSpecList module_specs;
                ModuleSpec matched_module_spec;
                if (dsym_fspec.Exists() &&
                    FileAtPathContainsArchAndUUID(dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr()))
                {
                    if (log)
                    {
                        log->Printf ("dSYM with matching UUID & arch found at %s", path);
                    }
                    return true;
                }
                else
                {
                    path[obj_file_path_length] = '\0';

                    char *last_dot = strrchr(path, '.');
                    while (last_dot != NULL && last_dot[0])
                    {
                        char *next_slash = strchr(last_dot, '/');
                        if (next_slash != NULL)
                        {
                            *next_slash = '\0';
                            ::strncat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path) - strlen(path) - 1);
                            ::strncat(path, exec_fspec->GetFilename().AsCString(), sizeof(path) - strlen(path) - 1);
                            dsym_fspec.SetFile(path, false);
                            if (dsym_fspec.Exists() &&
                                FileAtPathContainsArchAndUUID(dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr()))
                            {
                                if (log)
                                {
                                    log->Printf ("dSYM with matching UUID & arch found at %s", path);
                                }
                                return true;
                            }
                            else
                            {
                                *last_dot = '\0';
                                char *prev_slash = strrchr(path, '/');
                                if (prev_slash != NULL)
                                    *prev_slash = '\0';
                                else
                                    break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
        }
    }
    dsym_fspec.Clear();
    return false;
}

FileSpec
LocateExecutableSymbolFileDsym (const ModuleSpec &module_spec)
{
    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
    const ArchSpec *arch = module_spec.GetArchitecturePtr();
    const UUID *uuid = module_spec.GetUUIDPtr();

    Timer scoped_timer (__PRETTY_FUNCTION__,
                        "LocateExecutableSymbolFileDsym (file = %s, arch = %s, uuid = %p)",
                        exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>",
                        arch ? arch->GetArchitectureName() : "<NULL>",
                        (const void*)uuid);

    FileSpec symbol_fspec;
    ModuleSpec dsym_module_spec;
    // First try and find the dSYM in the same directory as the executable or in
    // an appropriate parent directory
    if (LocateDSYMInVincinityOfExecutable (module_spec, symbol_fspec) == false)
    {
        // We failed to easily find the dSYM above, so use DebugSymbols
        LocateMacOSXFilesUsingDebugSymbols (module_spec, dsym_module_spec);
    }
    else
    {
        dsym_module_spec.GetSymbolFileSpec() = symbol_fspec;
    }
    return dsym_module_spec.GetSymbolFileSpec();
}

ModuleSpec
Symbols::LocateExecutableObjectFile (const ModuleSpec &module_spec)
{
    ModuleSpec result;
    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
    const ArchSpec *arch = module_spec.GetArchitecturePtr();
    const UUID *uuid = module_spec.GetUUIDPtr();
    Timer scoped_timer (__PRETTY_FUNCTION__,
                        "LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)",
                        exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>",
                        arch ? arch->GetArchitectureName() : "<NULL>",
                        (const void*)uuid);

    ModuleSpecList module_specs;
    ModuleSpec matched_module_spec;
    if (exec_fspec &&
        ObjectFile::GetModuleSpecifications(*exec_fspec, 0, 0, module_specs) &&
        module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
    {
        result.GetFileSpec() = exec_fspec;
    }
    else
    {
        LocateMacOSXFilesUsingDebugSymbols (module_spec, result);
    }
    return result;
}

FileSpec
Symbols::LocateExecutableSymbolFile (const ModuleSpec &module_spec)
{
    FileSpec symbol_file_spec = module_spec.GetSymbolFileSpec();
    if (symbol_file_spec.IsAbsolute() && symbol_file_spec.Exists())
        return symbol_file_spec;

    const char *symbol_filename = symbol_file_spec.GetFilename().AsCString();
    if (symbol_filename && symbol_filename[0])
    {
        FileSpecList debug_file_search_paths (Target::GetDefaultDebugFileSearchPaths());

        // Add module directory.
        const ConstString &file_dir = module_spec.GetFileSpec().GetDirectory();
        debug_file_search_paths.AppendIfUnique (FileSpec(file_dir.AsCString("."), true));

        // Add current working directory.
        debug_file_search_paths.AppendIfUnique (FileSpec(".", true));

#ifndef LLVM_ON_WIN32
        // Add /usr/lib/debug directory.
        debug_file_search_paths.AppendIfUnique (FileSpec("/usr/lib/debug", true));
#endif // LLVM_ON_WIN32

        std::string uuid_str;
        const UUID &module_uuid = module_spec.GetUUID();
        if (module_uuid.IsValid())
        {
            // Some debug files are stored in the .build-id directory like this:
            //   /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug
            uuid_str = module_uuid.GetAsString("");
            uuid_str.insert (2, 1, '/');
            uuid_str = uuid_str + ".debug";
        }

        size_t num_directories = debug_file_search_paths.GetSize();
        for (size_t idx = 0; idx < num_directories; ++idx)
        {
            FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex (idx);
            dirspec.ResolvePath();
            if (!dirspec.Exists() || !dirspec.IsDirectory())
                continue;

            std::vector<std::string> files;
            std::string dirname = dirspec.GetPath();

            files.push_back (dirname + "/" + symbol_filename);
            files.push_back (dirname + "/.debug/" + symbol_filename);
            files.push_back (dirname + "/.build-id/" + uuid_str);

            // Some debug files may stored in the module directory like this:
            //   /usr/lib/debug/usr/lib/library.so.debug
            if (!file_dir.IsEmpty())
                files.push_back (dirname + file_dir.AsCString() + "/" + symbol_filename);

            const uint32_t num_files = files.size();
            for (size_t idx_file = 0; idx_file < num_files; ++idx_file)
            {
                const std::string &filename = files[idx_file];
                FileSpec file_spec (filename.c_str(), true);

                if (llvm::sys::fs::equivalent (file_spec.GetPath(), module_spec.GetFileSpec().GetPath()))
                    continue;

                if (file_spec.Exists())
                {
                    lldb_private::ModuleSpecList specs;
                    const size_t num_specs = ObjectFile::GetModuleSpecifications (file_spec, 0, 0, specs);
                    assert (num_specs <= 1 && "Symbol Vendor supports only a single architecture");
                    if (num_specs == 1)
                    {
                        ModuleSpec mspec;
                        if (specs.GetModuleSpecAtIndex (0, mspec))
                        {
                            if (mspec.GetUUID() == module_uuid)
                                return file_spec;
                        }
                    }
                }
            }
        }
    }

    return LocateExecutableSymbolFileDsym(module_spec);
}

#if !defined (__APPLE__)

FileSpec
Symbols::FindSymbolFileInBundle (const FileSpec& symfile_bundle,
                                 const lldb_private::UUID *uuid,
                                 const ArchSpec *arch)
{
    // FIXME
    return FileSpec();
}

bool
Symbols::DownloadObjectAndSymbolFile (ModuleSpec &module_spec, bool force_lookup)
{
    // Fill in the module_spec.GetFileSpec() for the object file and/or the
    // module_spec.GetSymbolFileSpec() for the debug symbols file.
    return false;
}

#endif
