/*
Copyright Paul Lin 2003. Copyright 2006 Bojan Resnik.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/

# include "jam.h"

# if defined( OS_NT ) || defined( OS_CYGWIN )

# include "lists.h"
# include "newstr.h"
# include "parse.h"
# include "frames.h"
# include "strings.h"

# define WIN32_LEAN_AND_MEAN
# include <windows.h>

# define  MAX_REGISTRY_DATA_LENGTH 4096
# define  MAX_REGISTRY_KEYNAME_LENGTH 256
# define  MAX_REGISTRY_VALUENAME_LENGTH 16384

typedef struct
{
    LPCSTR  name;
    HKEY    value;
} KeyMap;

static const KeyMap dlRootKeys[] = {
    { "HKLM", HKEY_LOCAL_MACHINE },
    { "HKCU", HKEY_CURRENT_USER },
    { "HKCR", HKEY_CLASSES_ROOT },
    { "HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE },
    { "HKEY_CURRENT_USER", HKEY_CURRENT_USER },
    { "HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT },
    { 0, 0 }
};

static HKEY get_key(char const** path)
{
    const KeyMap *p;

    for (p = dlRootKeys; p->name; ++p)
    {
        int n = strlen(p->name);
        if (!strncmp(*path,p->name,n))
        {
            if ((*path)[n] == '\\' || (*path)[n] == 0)
            {
                *path += n + 1;
                break;
            }
        }
    }

    return p->value;
}

LIST*
builtin_system_registry(
    PARSE    *parse,
    FRAME    *frame )
{
    char const* path = lol_get(frame->args, 0)->string;
    LIST* result = L0;
    HKEY key = get_key(&path);

    if (
        key != 0
        && ERROR_SUCCESS == RegOpenKeyEx(key, path, 0, KEY_QUERY_VALUE, &key)
    )
    {
        DWORD  type;
        BYTE   data[MAX_REGISTRY_DATA_LENGTH];
        DWORD  len = sizeof(data);
        LIST const* const field = lol_get(frame->args, 1);

        if ( ERROR_SUCCESS ==
             RegQueryValueEx(key, field ? field->string : 0, 0, &type, data, &len) )
        {
            switch (type)
            {

             case REG_EXPAND_SZ:
                 {
                     long len;
                     string expanded[1];
                     string_new(expanded);

                     while (
                         (len = ExpandEnvironmentStrings(
                             (LPCSTR)data, expanded->value, expanded->capacity))
                         > expanded->capacity
                     )
                         string_reserve(expanded, len);

                     expanded->size = len - 1;

                     result = list_new( result, newstr(expanded->value) );
                     string_free( expanded );
                 }
                 break;

             case REG_MULTI_SZ:
                 {
                     char* s;

                     for (s = (char*)data; *s; s += strlen(s) + 1)
                         result = list_new( result, newstr(s) );

                 }
                 break;

             case REG_DWORD:
                 {
                     char buf[100];
                     sprintf( buf, "%u", *(PDWORD)data );
                     result = list_new( result, newstr(buf) );
                 }
                 break;

             case REG_SZ:
                 result = list_new( result, newstr((char*)data) );
                 break;
            }
        }
        RegCloseKey(key);
    }
    return  result;
}

static LIST* get_subkey_names(HKEY key, char const* path)
{
    LIST* result = 0;

    if ( ERROR_SUCCESS ==
         RegOpenKeyEx(key, path, 0, KEY_ENUMERATE_SUB_KEYS, &key)
    )
    {
        char name[MAX_REGISTRY_KEYNAME_LENGTH];
        DWORD name_size = sizeof(name);
        DWORD index;
        FILETIME last_write_time;

        for ( index = 0;
              ERROR_SUCCESS == RegEnumKeyEx(
                  key, index, name, &name_size, 0, 0, 0, &last_write_time);
              ++index,
              name_size = sizeof(name)
        )
        {
            name[name_size] = 0;
            result = list_append(result, list_new(0, newstr(name)));
        }

        RegCloseKey(key);
    }

    return result;
}

static LIST* get_value_names(HKEY key, char const* path)
{
    LIST* result = 0;

    if ( ERROR_SUCCESS == RegOpenKeyEx(key, path, 0, KEY_QUERY_VALUE, &key) )
    {
        char name[MAX_REGISTRY_VALUENAME_LENGTH];
        DWORD name_size = sizeof(name);
        DWORD index;

        for ( index = 0;
              ERROR_SUCCESS == RegEnumValue(
                  key, index, name, &name_size, 0, 0, 0, 0);
              ++index,
              name_size = sizeof(name)
        )
        {
            name[name_size] = 0;
            result = list_append(result, list_new(0, newstr(name)));
        }

        RegCloseKey(key);
    }

    return result;
}

LIST*
builtin_system_registry_names(
    PARSE    *parse,
    FRAME    *frame )
{
    char const* path        = lol_get(frame->args, 0)->string;
    char const* result_type = lol_get(frame->args, 1)->string;

    HKEY key = get_key(&path);

    if ( !strcmp(result_type, "subkeys") )
        return get_subkey_names(key, path);
    if ( !strcmp(result_type, "values") )
        return get_value_names(key, path);
    return 0;
}

# endif
