//===-- Language.cpp -------------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <functional>
#include <map>
#include <mutex>

#include "lldb/Target/Language.h"

#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Stream.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;

typedef std::unique_ptr<Language> LanguageUP;
typedef std::map<lldb::LanguageType, LanguageUP> LanguagesMap;

static LanguagesMap&
GetLanguagesMap ()
{
    static LanguagesMap *g_map = nullptr;
    static std::once_flag g_initialize;
    
    std::call_once(g_initialize, [] {
        g_map = new LanguagesMap(); // NOTE: INTENTIONAL LEAK due to global destructor chain
    });
    
    return *g_map;
}
static std::mutex &
GetLanguagesMutex()
{
    static std::mutex *g_mutex = nullptr;
    static std::once_flag g_initialize;

    std::call_once(g_initialize, [] {
        g_mutex = new std::mutex(); // NOTE: INTENTIONAL LEAK due to global destructor chain
    });

    return *g_mutex;
}

Language*
Language::FindPlugin (lldb::LanguageType language)
{
    std::lock_guard<std::mutex> guard(GetLanguagesMutex());
    LanguagesMap& map(GetLanguagesMap());
    auto iter = map.find(language), end = map.end();
    if (iter != end)
        return iter->second.get();
    
    Language *language_ptr = nullptr;
    LanguageCreateInstance create_callback;
    
    for (uint32_t idx = 0;
         (create_callback = PluginManager::GetLanguageCreateCallbackAtIndex(idx)) != nullptr;
         ++idx)
    {
        language_ptr = create_callback(language);
        
        if (language_ptr)
        {
            map[language] = std::unique_ptr<Language>(language_ptr);
            return language_ptr;
        }
    }
    
    return nullptr;
}

void
Language::ForEach (std::function<bool(Language*)> callback)
{
    std::lock_guard<std::mutex> guard(GetLanguagesMutex());
    LanguagesMap& map(GetLanguagesMap());
    for (const auto& entry : map)
    {
        if (!callback(entry.second.get()))
            break;
    }
}

bool
Language::IsTopLevelFunction (Function& function)
{
    return false;
}

lldb::TypeCategoryImplSP
Language::GetFormatters ()
{
    return nullptr;
}

HardcodedFormatters::HardcodedFormatFinder
Language::GetHardcodedFormats ()
{
    return {};
}

HardcodedFormatters::HardcodedSummaryFinder
Language::GetHardcodedSummaries ()
{
    return {};
}

HardcodedFormatters::HardcodedSyntheticFinder
Language::GetHardcodedSynthetics ()
{
    return {};
}

HardcodedFormatters::HardcodedValidatorFinder
Language::GetHardcodedValidators ()
{
    return {};
}

std::vector<ConstString>
Language::GetPossibleFormattersMatches (ValueObject& valobj, lldb::DynamicValueType use_dynamic)
{
    return {};
}

lldb_private::formatters::StringPrinter::EscapingHelper
Language::GetStringPrinterEscapingHelper (lldb_private::formatters::StringPrinter::GetPrintableElementType elem_type)
{
    return StringPrinter::GetDefaultEscapingHelper(elem_type);
}

struct language_name_pair {
    const char *name;
    LanguageType type;
};

struct language_name_pair language_names[] =
{
    // To allow GetNameForLanguageType to be a simple array lookup, the first
    // part of this array must follow enum LanguageType exactly.
    {   "unknown",          eLanguageTypeUnknown        },
    {   "c89",              eLanguageTypeC89            },
    {   "c",                eLanguageTypeC              },
    {   "ada83",            eLanguageTypeAda83          },
    {   "c++",              eLanguageTypeC_plus_plus    },
    {   "cobol74",          eLanguageTypeCobol74        },
    {   "cobol85",          eLanguageTypeCobol85        },
    {   "fortran77",        eLanguageTypeFortran77      },
    {   "fortran90",        eLanguageTypeFortran90      },
    {   "pascal83",         eLanguageTypePascal83       },
    {   "modula2",          eLanguageTypeModula2        },
    {   "java",             eLanguageTypeJava           },
    {   "c99",              eLanguageTypeC99            },
    {   "ada95",            eLanguageTypeAda95          },
    {   "fortran95",        eLanguageTypeFortran95      },
    {   "pli",              eLanguageTypePLI            },
    {   "objective-c",      eLanguageTypeObjC           },
    {   "objective-c++",    eLanguageTypeObjC_plus_plus },
    {   "upc",              eLanguageTypeUPC            },
    {   "d",                eLanguageTypeD              },
    {   "python",           eLanguageTypePython         },
    {   "opencl",           eLanguageTypeOpenCL         },
    {   "go",               eLanguageTypeGo             },
    {   "modula3",          eLanguageTypeModula3        },
    {   "haskell",          eLanguageTypeHaskell        },
    {   "c++03",            eLanguageTypeC_plus_plus_03 },
    {   "c++11",            eLanguageTypeC_plus_plus_11 },
    {   "ocaml",            eLanguageTypeOCaml          },
    {   "rust",             eLanguageTypeRust           },
    {   "c11",              eLanguageTypeC11            },
    {   "swift",            eLanguageTypeSwift          },
    {   "julia",            eLanguageTypeJulia          },
    {   "dylan",            eLanguageTypeDylan          },
    {   "c++14",            eLanguageTypeC_plus_plus_14 },
    {   "fortran03",        eLanguageTypeFortran03      },
    {   "fortran08",        eLanguageTypeFortran08      },
    // Vendor Extensions
    {   "mipsassem",        eLanguageTypeMipsAssembler  },
    {   "renderscript",     eLanguageTypeExtRenderScript},
    // Now synonyms, in arbitrary order
    {   "objc",             eLanguageTypeObjC           },
    {   "objc++",           eLanguageTypeObjC_plus_plus },
    {   "pascal",           eLanguageTypePascal83       }
};

static uint32_t num_languages = sizeof(language_names) / sizeof (struct language_name_pair);

LanguageType
Language::GetLanguageTypeFromString (const char *string)
{
    for (uint32_t i = 0; i < num_languages; i++)
    {
        if (strcasecmp (language_names[i].name, string) == 0)
            return (LanguageType) language_names[i].type;
    }
    return eLanguageTypeUnknown;
}

const char *
Language::GetNameForLanguageType (LanguageType language)
{
    if (language < num_languages)
        return language_names[language].name;
    else
        return language_names[eLanguageTypeUnknown].name;
}

void
Language::PrintAllLanguages (Stream &s, const char *prefix, const char *suffix)
{
    for (uint32_t i = 1; i < num_languages; i++)
    {
        s.Printf("%s%s%s", prefix, language_names[i].name, suffix);
    }
}

void
Language::ForAllLanguages (std::function<bool(lldb::LanguageType)> callback)
{
    for (uint32_t i = 1; i < num_languages; i++)
    {
        if (!callback(language_names[i].type))
            break;
    }
}

bool
Language::LanguageIsCPlusPlus (LanguageType language)
{
    switch (language)
    {
        case eLanguageTypeC_plus_plus:
        case eLanguageTypeC_plus_plus_03:
        case eLanguageTypeC_plus_plus_11:
        case eLanguageTypeC_plus_plus_14:
        case eLanguageTypeObjC_plus_plus:
            return true;
        default:
            return false;
    }
}

bool
Language::LanguageIsObjC (LanguageType language)
{
    switch (language)
    {
        case eLanguageTypeObjC:
        case eLanguageTypeObjC_plus_plus:
            return true;
        default:
            return false;
    }
}

bool
Language::LanguageIsC (LanguageType language)
{
    switch (language)
    {
        case eLanguageTypeC:
        case eLanguageTypeC89:
        case eLanguageTypeC99:
        case eLanguageTypeC11:
            return true;
        default:
            return false;
    }
}

bool
Language::LanguageIsPascal (LanguageType language)
{
    switch (language)
    {
        case eLanguageTypePascal83:
            return true;
        default:
            return false;
    }
}

LanguageType
Language::GetPrimaryLanguage (LanguageType language)
{
    switch (language)
    {
        case eLanguageTypeC_plus_plus:
        case eLanguageTypeC_plus_plus_03:
        case eLanguageTypeC_plus_plus_11:
        case eLanguageTypeC_plus_plus_14:
            return eLanguageTypeC_plus_plus;
        case eLanguageTypeC:
        case eLanguageTypeC89:
        case eLanguageTypeC99:
        case eLanguageTypeC11:
            return eLanguageTypeC;
        case eLanguageTypeObjC:
        case eLanguageTypeObjC_plus_plus:
            return eLanguageTypeObjC;
        case eLanguageTypePascal83:
        case eLanguageTypeCobol74:
        case eLanguageTypeCobol85:
        case eLanguageTypeFortran77:
        case eLanguageTypeFortran90:
        case eLanguageTypeFortran95:
        case eLanguageTypeFortran03:
        case eLanguageTypeFortran08:
        case eLanguageTypeAda83:
        case eLanguageTypeAda95:
        case eLanguageTypeModula2:
        case eLanguageTypeJava:
        case eLanguageTypePLI:
        case eLanguageTypeUPC:
        case eLanguageTypeD:
        case eLanguageTypePython:
        case eLanguageTypeOpenCL:
        case eLanguageTypeGo:
        case eLanguageTypeModula3:
        case eLanguageTypeHaskell:
        case eLanguageTypeOCaml:
        case eLanguageTypeRust:
        case eLanguageTypeSwift:
        case eLanguageTypeJulia:
        case eLanguageTypeDylan:
        case eLanguageTypeMipsAssembler:
        case eLanguageTypeExtRenderScript:
        case eLanguageTypeUnknown:
        default:
            return language;
    }
}

void
Language::GetLanguagesSupportingTypeSystems (std::set<lldb::LanguageType> &languages,
                                             std::set<lldb::LanguageType> &languages_for_expressions)
{
    uint32_t idx = 0;
    
    while (TypeSystemEnumerateSupportedLanguages enumerate = PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(idx++))
    {
        (*enumerate)(languages, languages_for_expressions);
    }
}

void
Language::GetLanguagesSupportingREPLs (std::set<lldb::LanguageType> &languages)
{
    uint32_t idx = 0;
    
    while (REPLEnumerateSupportedLanguages enumerate = PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(idx++))
    {
        (*enumerate)(languages);
    }
}

std::unique_ptr<Language::TypeScavenger>
Language::GetTypeScavenger ()
{
    return nullptr;
}

const char*
Language::GetLanguageSpecificTypeLookupHelp ()
{
    return nullptr;
}

size_t
Language::TypeScavenger::Find (ExecutionContextScope *exe_scope,
                               const char *key,
                               ResultSet &results,
                               bool append)
{
    if (!exe_scope || !exe_scope->CalculateTarget().get())
        return false;
    
    if (!key || !key[0])
        return false;

    if (!append)
        results.clear();
    
    size_t old_size = results.size();
    
    if (this->Find_Impl(exe_scope, key, results))
        return results.size() - old_size;
    return 0;
}

bool
Language::GetFormatterPrefixSuffix (ValueObject& valobj, ConstString type_hint,
                                    std::string& prefix, std::string& suffix)
{
    return false;
}

DumpValueObjectOptions::DeclPrintingHelper
Language::GetDeclPrintingHelper ()
{
    return nullptr;
}

LazyBool
Language::IsLogicalTrue (ValueObject& valobj,
                         Error& error)
{
    return eLazyBoolCalculate;
}

bool
Language::IsNilReference (ValueObject& valobj)
{
    return false;
}

bool
Language::IsUninitializedReference (ValueObject& valobj)
{
    return false;
}

bool
Language::GetFunctionDisplayName (const SymbolContext *sc,
                                  const ExecutionContext *exe_ctx,
                                  FunctionNameRepresentation representation,
                                  Stream& s)
{
    return false;
}

void
Language::GetExceptionResolverDescription(bool catch_on, bool throw_on, Stream &s)
{
    GetDefaultExceptionResolverDescription(catch_on, throw_on, s);
}

void
Language::GetDefaultExceptionResolverDescription(bool catch_on, bool throw_on, Stream &s)
{
     s.Printf ("Exception breakpoint (catch: %s throw: %s)",
               catch_on ? "on" : "off",
               throw_on ? "on" : "off");
}
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
Language::Language()
{
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
Language::~Language()
{
}
