//===-- OptionGroupPlatform.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"

#include "lldb/Interpreter/OptionGroupPlatform.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Target/Platform.h"
#include "lldb/Utility/Utils.h"

using namespace lldb;
using namespace lldb_private;

PlatformSP 
OptionGroupPlatform::CreatePlatformWithOptions (CommandInterpreter &interpreter,
                                                const ArchSpec &arch,
                                                bool make_selected,
                                                Error& error,
                                                ArchSpec &platform_arch) const
{
    PlatformSP platform_sp;
    
    if (!m_platform_name.empty())
    {
        platform_sp = Platform::Create (m_platform_name.c_str(), error);
        if (platform_sp)
        {
            if (platform_arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch))
            {
                error.SetErrorStringWithFormat ("platform '%s' doesn't support '%s'",
                                                platform_sp->GetName().GetCString(),
                                                arch.GetTriple().getTriple().c_str());
                platform_sp.reset();
                return platform_sp;
            }
        }
    }
    else if (arch.IsValid())
    {
        platform_sp = Platform::Create (arch, &platform_arch, error);
    }
    
    if (platform_sp)
    {
        interpreter.GetDebugger().GetPlatformList().Append (platform_sp, make_selected);
        if (m_os_version_major != UINT32_MAX)
        {
            platform_sp->SetOSVersion (m_os_version_major,
                                       m_os_version_minor,
                                       m_os_version_update);
        }
        
        if (m_sdk_sysroot)
            platform_sp->SetSDKRootDirectory (m_sdk_sysroot);
        
        if (m_sdk_build)
            platform_sp->SetSDKBuild (m_sdk_build);
    }

    return platform_sp;
}

void
OptionGroupPlatform::OptionParsingStarting (CommandInterpreter &interpreter)
{
    m_platform_name.clear();
    m_sdk_sysroot.Clear();
    m_sdk_build.Clear();
    m_os_version_major = UINT32_MAX;
    m_os_version_minor = UINT32_MAX;
    m_os_version_update = UINT32_MAX;
}

static OptionDefinition
g_option_table[] =
{
    { LLDB_OPT_SET_ALL, false, "platform", 'p', required_argument, NULL, 0, eArgTypePlatform, "Specify name of the platform to use for this target, creating the platform if necessary."},
    { LLDB_OPT_SET_ALL, false, "version" , 'v', required_argument, NULL, 0, eArgTypeNone, "Specify the initial SDK version to use prior to connecting." },
    { LLDB_OPT_SET_ALL, false, "build"   , 'b', required_argument, NULL, 0, eArgTypeNone, "Specify the initial SDK build number." },
    { LLDB_OPT_SET_ALL, false, "sysroot" , 'S', required_argument, NULL, 0, eArgTypeFilename, "Specify the SDK root directory that contains a root of all remote system files." }
};

const OptionDefinition*
OptionGroupPlatform::GetDefinitions ()
{
    if (m_include_platform_option)
        return g_option_table;
    return g_option_table + 1;
}

uint32_t
OptionGroupPlatform::GetNumDefinitions ()
{
    if (m_include_platform_option)
        return llvm::array_lengthof(g_option_table);
    return llvm::array_lengthof(g_option_table) - 1;
}


Error
OptionGroupPlatform::SetOptionValue (CommandInterpreter &interpreter,
                                     uint32_t option_idx,
                                     const char *option_arg)
{
    Error error;
    if (!m_include_platform_option)
        ++option_idx;
    
    const int short_option = g_option_table[option_idx].short_option;
    
    switch (short_option)
    {
        case 'p':
            m_platform_name.assign (option_arg);
            break;
            
        case 'v':
            if (Args::StringToVersion (option_arg, 
                                       m_os_version_major, 
                                       m_os_version_minor, 
                                       m_os_version_update) == option_arg)
                error.SetErrorStringWithFormat ("invalid version string '%s'", option_arg);
            break;
            
        case 'b':
            m_sdk_build.SetCString (option_arg);
            break;
            
        case 'S':
            m_sdk_sysroot.SetCString (option_arg);
            break;

        default:
            error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
            break;
    }
    return error;
}
