//===-- TargetList.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
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Event.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/State.h"
#include "lldb/Core/Timer.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/OptionGroupPlatform.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/TargetList.h"

#include "llvm/ADT/SmallString.h"

using namespace lldb;
using namespace lldb_private;

ConstString &
TargetList::GetStaticBroadcasterClass ()
{
    static ConstString class_name ("lldb.targetList");
    return class_name;
}

//----------------------------------------------------------------------
// TargetList constructor
//----------------------------------------------------------------------
TargetList::TargetList(Debugger &debugger) :
    Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()),
    m_target_list(),
    m_target_list_mutex (Mutex::eMutexTypeRecursive),
    m_selected_target_idx (0)
{
    CheckInWithManager();
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
TargetList::~TargetList()
{
    Mutex::Locker locker(m_target_list_mutex);
    m_target_list.clear();
}

Error
TargetList::CreateTarget (Debugger &debugger,
                          const char *user_exe_path,
                          const char *triple_cstr,
                          bool get_dependent_files,
                          const OptionGroupPlatform *platform_options,
                          TargetSP &target_sp)
{
    return CreateTargetInternal (debugger,
                                 user_exe_path,
                                 triple_cstr,
                                 get_dependent_files,
                                 platform_options,
                                 target_sp,
                                 false);
}

Error
TargetList::CreateTarget (Debugger &debugger,
                          const char *user_exe_path,
                          const ArchSpec& specified_arch,
                          bool get_dependent_files,
                          PlatformSP &platform_sp,
                          TargetSP &target_sp)
{
    return CreateTargetInternal (debugger,
                                 user_exe_path,
                                 specified_arch,
                                 get_dependent_files,
                                 platform_sp,
                                 target_sp,
                                 false);
}

Error
TargetList::CreateTargetInternal (Debugger &debugger,
                                  const char *user_exe_path,
                                  const char *triple_cstr,
                                  bool get_dependent_files,
                                  const OptionGroupPlatform *platform_options,
                                  TargetSP &target_sp,
                                  bool is_dummy_target)
{
    Error error;
    PlatformSP platform_sp;
    
    // This is purposely left empty unless it is specified by triple_cstr.
    // If not initialized via triple_cstr, then the currently selected platform
    // will set the architecture correctly.
    const ArchSpec arch(triple_cstr);
    if (triple_cstr && triple_cstr[0])
    {
        if (!arch.IsValid())
        {
            error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr);
            return error;
        }
    }
    
    ArchSpec platform_arch(arch);

    bool prefer_platform_arch = false;
    
    CommandInterpreter &interpreter = debugger.GetCommandInterpreter();

    // let's see if there is already an existing plaform before we go creating another...
    platform_sp = debugger.GetPlatformList().GetSelectedPlatform();

    if (platform_options && platform_options->PlatformWasSpecified ())
    {
        // Create a new platform if it doesn't match the selected platform
        if (!platform_options->PlatformMatches(platform_sp))
        {
            const bool select_platform = true;
            platform_sp = platform_options->CreatePlatformWithOptions (interpreter,
                                                                       arch,
                                                                       select_platform,
                                                                       error,
                                                                       platform_arch);
            if (!platform_sp)
                return error;
        }
    }
    
    if (user_exe_path && user_exe_path[0])
    {
        ModuleSpecList module_specs;
        ModuleSpec module_spec;
        module_spec.GetFileSpec().SetFile(user_exe_path, true);
        
        // Resolve the executable in case we are given a path to a application bundle
        // like a .app bundle on MacOSX
        Host::ResolveExecutableInBundle (module_spec.GetFileSpec());

        lldb::offset_t file_offset = 0;
        lldb::offset_t file_size = 0;
        const size_t num_specs = ObjectFile::GetModuleSpecifications (module_spec.GetFileSpec(), file_offset, file_size, module_specs);
        if (num_specs > 0)
        {
            ModuleSpec matching_module_spec;

            if (num_specs == 1)
            {
                if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec))
                {
                    if (platform_arch.IsValid())
                    {
                        if (platform_arch.IsCompatibleMatch(matching_module_spec.GetArchitecture()))
                        {
                            // If the OS or vendor weren't specified, then adopt the module's
                            // architecture so that the platform matching can be more accurate
                            if (!platform_arch.TripleOSWasSpecified() || !platform_arch.TripleVendorWasSpecified())
                            {
                                prefer_platform_arch = true;
                                platform_arch = matching_module_spec.GetArchitecture();
                            }
                        }
                        else
                        {
                            error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'",
                                                           platform_arch.GetTriple().str().c_str(),
                                                           matching_module_spec.GetArchitecture().GetTriple().str().c_str(),
                                                           module_spec.GetFileSpec().GetPath().c_str());
                            return error;
                        }
                    }
                    else
                    {
                        // Only one arch and none was specified
                        prefer_platform_arch = true;
                        platform_arch = matching_module_spec.GetArchitecture();
                    }
                }
            }
            else
            {
                if (arch.IsValid())
                {
                    module_spec.GetArchitecture() = arch;
                    if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec))
                    {
                        prefer_platform_arch = true;
                        platform_arch = matching_module_spec.GetArchitecture();
                    }
                }
                else
                {
                    // No architecture specified, check if there is only one platform for
                    // all of the architectures.
                    
                    typedef std::vector<PlatformSP> PlatformList;
                    PlatformList platforms;
                    PlatformSP host_platform_sp = Platform::GetHostPlatform();
                    for (size_t i=0; i<num_specs; ++i)
                    {
                        ModuleSpec module_spec;
                        if (module_specs.GetModuleSpecAtIndex(i, module_spec))
                        {
                            // See if there was a selected platform and check that first
                            // since the user may have specified it.
                            if (platform_sp)
                            {
                                if (platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, NULL))
                                {
                                    platforms.push_back(platform_sp);
                                    continue;
                                }
                            }
                            
                            // Next check the host platform it if wasn't already checked above
                            if (host_platform_sp && (!platform_sp || host_platform_sp->GetName() != platform_sp->GetName()))
                            {
                                if (host_platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, NULL))
                                {
                                    platforms.push_back(host_platform_sp);
                                    continue;
                                }
                            }
                            
                            // Just find a platform that matches the architecture in the executable file
                            platforms.push_back(Platform::GetPlatformForArchitecture(module_spec.GetArchitecture(), nullptr));
                        }
                    }
                    
                    Platform *platform_ptr = NULL;
                    for (const auto &the_platform_sp : platforms)
                    {
                        if (platform_ptr)
                        {
                            if (platform_ptr->GetName() != the_platform_sp->GetName())
                            {
                                platform_ptr = NULL;
                                break;
                            }
                        }
                        else
                        {
                            platform_ptr = the_platform_sp.get();
                        }
                    }
                    
                    if (platform_ptr)
                    {
                        // All platforms for all modules in the exectuable match, so we can select this platform
                        platform_sp = platforms.front();
                    }
                    else
                    {
                        // More than one platform claims to support this file, so the --platform option must be specified
                        StreamString error_strm;
                        std::set<Platform *> platform_set;
                        error_strm.Printf ("more than one platform supports this executable (");
                        for (const auto &the_platform_sp : platforms)
                        {
                            if (platform_set.find(the_platform_sp.get()) == platform_set.end())
                            {
                                if (!platform_set.empty())
                                    error_strm.PutCString(", ");
                                error_strm.PutCString(the_platform_sp->GetName().GetCString());
                                platform_set.insert(the_platform_sp.get());
                            }
                        }
                        error_strm.Printf("), use the --platform option to specify a platform");
                        error.SetErrorString(error_strm.GetString().c_str());
                        return error;
                    }
                }
            }
        }
    }

    // If we have a valid architecture, make sure the current platform is
    // compatible with that architecture
    if (!prefer_platform_arch && arch.IsValid())
    {
        if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch))
        {
            platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch);
            if (!is_dummy_target && platform_sp)
                debugger.GetPlatformList().SetSelectedPlatform(platform_sp);
        }
    }
    else if (platform_arch.IsValid())
    {
        // if "arch" isn't valid, yet "platform_arch" is, it means we have an executable file with
        // a single architecture which should be used
        ArchSpec fixed_platform_arch;
        if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, &fixed_platform_arch))
        {
            platform_sp = Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch);
            if (!is_dummy_target && platform_sp)
                debugger.GetPlatformList().SetSelectedPlatform(platform_sp);
        }
    }
    
    if (!platform_arch.IsValid())
        platform_arch = arch;

    error = TargetList::CreateTargetInternal (debugger,
                                              user_exe_path,
                                              platform_arch,
                                              get_dependent_files,
                                              platform_sp,
                                              target_sp,
                                              is_dummy_target);
    return error;
}

lldb::TargetSP
TargetList::GetDummyTarget (lldb_private::Debugger &debugger)
{
    // FIXME: Maybe the dummy target should be per-Debugger
    if (!m_dummy_target_sp || !m_dummy_target_sp->IsValid())
    {
        ArchSpec arch(Target::GetDefaultArchitecture());
        if (!arch.IsValid())
            arch = HostInfo::GetArchitecture();
        Error err = CreateDummyTarget(debugger,
                                      arch.GetTriple().getTriple().c_str(),
                                      m_dummy_target_sp);
    }

    return m_dummy_target_sp;
}

Error
TargetList::CreateDummyTarget (Debugger &debugger,
                               const char *specified_arch_name,
                               lldb::TargetSP &target_sp)
{
    PlatformSP host_platform_sp(Platform::GetHostPlatform());
    return CreateTargetInternal (debugger,
                                 (const char *) nullptr,
                                 specified_arch_name,
                                 false,
                                 (const OptionGroupPlatform *) nullptr,
                                 target_sp,
                                 true);
}

Error
TargetList::CreateTargetInternal (Debugger &debugger,
                                  const char *user_exe_path,
                                  const ArchSpec& specified_arch,
                                  bool get_dependent_files,
                                  lldb::PlatformSP &platform_sp,
                                  lldb::TargetSP &target_sp,
                                  bool is_dummy_target)
{

    Timer scoped_timer (__PRETTY_FUNCTION__,
                        "TargetList::CreateTarget (file = '%s', arch = '%s')",
                        user_exe_path,
                        specified_arch.GetArchitectureName());
    Error error;

    ArchSpec arch(specified_arch);

    if (arch.IsValid())
    {
        if (!platform_sp || !platform_sp->IsCompatibleArchitecture(arch, false, NULL))
            platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
    }
    
    if (!platform_sp)
        platform_sp = debugger.GetPlatformList().GetSelectedPlatform();

    if (!arch.IsValid())
        arch = specified_arch;

    FileSpec file (user_exe_path, false);
    if (!file.Exists() && user_exe_path && user_exe_path[0] == '~')
    {
        // we want to expand the tilde but we don't want to resolve any symbolic links
        // so we can't use the FileSpec constructor's resolve flag
        llvm::SmallString<64> unglobbed_path(user_exe_path);
        FileSpec::ResolveUsername(unglobbed_path);

        if (unglobbed_path.empty())
            file = FileSpec(user_exe_path, false);
        else
            file = FileSpec(unglobbed_path.c_str(), false);
    }

    bool user_exe_path_is_bundle = false;
    char resolved_bundle_exe_path[PATH_MAX];
    resolved_bundle_exe_path[0] = '\0';
    if (file)
    {
        if (file.GetFileType() == FileSpec::eFileTypeDirectory)
            user_exe_path_is_bundle = true;

        if (file.IsRelative() && user_exe_path)
        {
            // Ignore paths that start with "./" and "../"
            if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') ||
                  (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/')))
            {
                char cwd[PATH_MAX];
                if (getcwd (cwd, sizeof(cwd)))
                {
                    std::string cwd_user_exe_path (cwd);
                    cwd_user_exe_path += '/';
                    cwd_user_exe_path += user_exe_path;
                    FileSpec cwd_file (cwd_user_exe_path.c_str(), false);
                    if (cwd_file.Exists())
                        file = cwd_file;
                }
            }
        }

        ModuleSP exe_module_sp;
        if (platform_sp)
        {
            FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
            ModuleSpec module_spec(file, arch);
            error = platform_sp->ResolveExecutable (module_spec,
                                                    exe_module_sp, 
                                                    executable_search_paths.GetSize() ? &executable_search_paths : NULL);
        }

        if (error.Success() && exe_module_sp)
        {
            if (exe_module_sp->GetObjectFile() == NULL)
            {
                if (arch.IsValid())
                {
                    error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s",
                                                   file.GetPath().c_str(),
                                                   arch.GetArchitectureName());
                }
                else
                {
                    error.SetErrorStringWithFormat("unsupported file type \"%s\"",
                                                   file.GetPath().c_str());
                }
                return error;
            }
            target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target));
            target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
            if (user_exe_path_is_bundle)
                exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path));
        }
    }
    else
    {
        // No file was specified, just create an empty target with any arch
        // if a valid arch was specified
        target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target));
    }

    if (target_sp)
    {
        // Set argv0 with what the user typed, unless the user specified a
        // directory. If the user specified a directory, then it is probably a
        // bundle that was resolved and we need to use the resolved bundle path
        if (user_exe_path)
        {
            // Use exactly what the user typed as the first argument when we exec or posix_spawn
            if (user_exe_path_is_bundle && resolved_bundle_exe_path[0])
            {
                target_sp->SetArg0 (resolved_bundle_exe_path);
            }
            else
            {
                // Use resolved path
                target_sp->SetArg0 (file.GetPath().c_str());
            }
        }
        if (file.GetDirectory())
        {
            FileSpec file_dir;
            file_dir.GetDirectory() = file.GetDirectory();
            target_sp->GetExecutableSearchPaths ().Append (file_dir);
        }

        // Don't put the dummy target in the target list, it's held separately.
        if (!is_dummy_target)
        {
            Mutex::Locker locker(m_target_list_mutex);
            m_selected_target_idx = m_target_list.size();
            m_target_list.push_back(target_sp);
            // Now prime this from the dummy target:
            target_sp->PrimeFromDummyTarget(debugger.GetDummyTarget());
        }
        else
        {
            m_dummy_target_sp = target_sp;
        }
    }

    return error;
}

bool
TargetList::DeleteTarget (TargetSP &target_sp)
{
    Mutex::Locker locker(m_target_list_mutex);
    collection::iterator pos, end = m_target_list.end();

    for (pos = m_target_list.begin(); pos != end; ++pos)
    {
        if (pos->get() == target_sp.get())
        {
            m_target_list.erase(pos);
            return true;
        }
    }
    return false;
}


TargetSP
TargetList::FindTargetWithExecutableAndArchitecture
(
    const FileSpec &exe_file_spec,
    const ArchSpec *exe_arch_ptr
) const
{
    Mutex::Locker locker (m_target_list_mutex);
    TargetSP target_sp;
    bool full_match = (bool)exe_file_spec.GetDirectory();

    collection::const_iterator pos, end = m_target_list.end();
    for (pos = m_target_list.begin(); pos != end; ++pos)
    {
        Module *exe_module = (*pos)->GetExecutableModulePointer();

        if (exe_module)
        {
            if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match))
            {
                if (exe_arch_ptr)
                {
                    if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture()))
                        continue;
                }
                target_sp = *pos;
                break;
            }
        }
    }
    return target_sp;
}

TargetSP
TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
{
    Mutex::Locker locker(m_target_list_mutex);
    TargetSP target_sp;
    collection::const_iterator pos, end = m_target_list.end();
    for (pos = m_target_list.begin(); pos != end; ++pos)
    {
        Process* process = (*pos)->GetProcessSP().get();
        if (process && process->GetID() == pid)
        {
            target_sp = *pos;
            break;
        }
    }
    return target_sp;
}


TargetSP
TargetList::FindTargetWithProcess (Process *process) const
{
    TargetSP target_sp;
    if (process)
    {
        Mutex::Locker locker(m_target_list_mutex);
        collection::const_iterator pos, end = m_target_list.end();
        for (pos = m_target_list.begin(); pos != end; ++pos)
        {
            if (process == (*pos)->GetProcessSP().get())
            {
                target_sp = *pos;
                break;
            }
        }
    }
    return target_sp;
}

TargetSP
TargetList::GetTargetSP (Target *target) const
{
    TargetSP target_sp;
    if (target)
    {
        Mutex::Locker locker(m_target_list_mutex);
        collection::const_iterator pos, end = m_target_list.end();
        for (pos = m_target_list.begin(); pos != end; ++pos)
        {
            if (target == (*pos).get())
            {
                target_sp = *pos;
                break;
            }
        }
    }
    return target_sp;
}

uint32_t
TargetList::SendAsyncInterrupt (lldb::pid_t pid)
{
    uint32_t num_async_interrupts_sent = 0;

    if (pid != LLDB_INVALID_PROCESS_ID)
    {
        TargetSP target_sp(FindTargetWithProcessID (pid));
        if (target_sp.get())
        {
            Process* process = target_sp->GetProcessSP().get();
            if (process)
            {
                process->SendAsyncInterrupt();
                ++num_async_interrupts_sent;
            }
        }
    }
    else
    {
        // We don't have a valid pid to broadcast to, so broadcast to the target
        // list's async broadcaster...
        BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
    }

    return num_async_interrupts_sent;
}

uint32_t
TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
{
    uint32_t num_signals_sent = 0;
    Process *process = NULL;
    if (pid == LLDB_INVALID_PROCESS_ID)
    {
        // Signal all processes with signal
        Mutex::Locker locker(m_target_list_mutex);
        collection::iterator pos, end = m_target_list.end();
        for (pos = m_target_list.begin(); pos != end; ++pos)
        {
            process = (*pos)->GetProcessSP().get();
            if (process)
            {
                if (process->IsAlive())
                {
                    ++num_signals_sent;
                    process->Signal (signo);
                }
            }
        }
    }
    else
    {
        // Signal a specific process with signal
        TargetSP target_sp(FindTargetWithProcessID (pid));
        if (target_sp.get())
        {
            process = target_sp->GetProcessSP().get();
            if (process)
            {
                if (process->IsAlive())
                {
                    ++num_signals_sent;
                    process->Signal (signo);
                }
            }
        }
    }
    return num_signals_sent;
}

int
TargetList::GetNumTargets () const
{
    Mutex::Locker locker (m_target_list_mutex);
    return m_target_list.size();
}

lldb::TargetSP
TargetList::GetTargetAtIndex (uint32_t idx) const
{
    TargetSP target_sp;
    Mutex::Locker locker (m_target_list_mutex);
    if (idx < m_target_list.size())
        target_sp = m_target_list[idx];
    return target_sp;
}

uint32_t
TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const
{
    Mutex::Locker locker (m_target_list_mutex);
    size_t num_targets = m_target_list.size();
    for (size_t idx = 0; idx < num_targets; idx++)
    {
        if (target_sp == m_target_list[idx])
            return idx;
    }
    return UINT32_MAX;
}

uint32_t
TargetList::SetSelectedTarget (Target* target)
{
    Mutex::Locker locker (m_target_list_mutex);
    collection::const_iterator pos,
        begin = m_target_list.begin(),
        end = m_target_list.end();
    for (pos = begin; pos != end; ++pos)
    {
        if (pos->get() == target)
        {
            m_selected_target_idx = std::distance (begin, pos);
            return m_selected_target_idx;
        }
    }
    m_selected_target_idx = 0;
    return m_selected_target_idx;
}

lldb::TargetSP
TargetList::GetSelectedTarget ()
{
    Mutex::Locker locker (m_target_list_mutex);
    if (m_selected_target_idx >= m_target_list.size())
        m_selected_target_idx = 0;
    return GetTargetAtIndex (m_selected_target_idx);
}
