/*
 * Windows regedit.exe registry editor implementation.
 *
 * Copyright 2002 Andriy Palamarchuk
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <ctype.h>
#include <stdio.h>
#include <windows.h>
#include "regproc.h"

static char *usage =
"Usage:\n"
"    regedit filename\n"
"    regedit /E filename [regpath]\n"
"    regedit /D regpath\n"
"\n"
"filename - registry file name\n"
"regpath - name of the registry key\n"
"\n"
"When is called without any switches adds contents of the specified\n"
"registry file to the registry\n"
"\n"
"Switches:\n"
"    /E - exports contents of the specified registry key to the specified\n"
"	file. Exports the whole registry if no key is specified.\n"
"    /D - deletes specified registry key\n"
"    /S - silent execution, can be used with any other switch.\n"
"	The only existing mode, exists for compatibility with Windows regedit.\n"
"    /V - advanced mode, can be used with any other switch.\n"
"	Ignored, exists for compatibility with Windows regedit.\n"
"    /L - location of system.dat file. Can be used with any other switch.\n"
"	Ignored. Exists for compatibility with Windows regedit.\n"
"    /R - location of user.dat file. Can be used with any other switch.\n"
"	Ignored. Exists for compatibility with Windows regedit.\n"
"    /? - print this help. Any other switches are ignored.\n"
"    /C - create registry from. Not implemented.\n"
"\n"
"The switches are case-insensitive, can be prefixed either by '-' or '/'.\n"
"This program is command-line compatible with Microsoft Windows\n"
"regedit. The difference with Windows regedit - this application has\n"
"command-line interface only.\n";

typedef enum {
    ACTION_UNDEF, ACTION_ADD, ACTION_EXPORT, ACTION_DELETE
} REGEDIT_ACTION;

/**
 * Process unknown switch.
 *
 * Params:
 *   chu - the switch character in upper-case.
 *   s - the command line string where s points to the switch character.
 */
void error_unknown_switch(char chu, char *s)
{
    if (isalpha(chu))
    {
        printf("%s: Undefined switch /%c!\n", getAppName(), chu);
    } else {
        printf("%s: Alphabetic character is expected after '%c' "
               "in switch specification\n", getAppName(), *(s - 1));
    }
    exit(1);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow)
{
    REGEDIT_ACTION action = ACTION_UNDEF;
    LPSTR s = lpCmdLine;        /* command line pointer */
    CHAR ch = *s;               /* current character */

    setAppName("regedit");
    while (ch && ((ch == '-') || (ch == '/')))
    {
        char chu;
        char ch2;

        s++;
        ch = *s;
        ch2 = *(s+1);
        chu = toupper(ch);
        if (!ch2 || isspace(ch2))
        {
            if (chu == 'S' || chu == 'V')
            {
                /* ignore these switches */
            } else {
                switch (chu)
                {
                case 'D':
                    action = ACTION_DELETE;
                    break;
                case 'E':
                    action = ACTION_EXPORT;
                    break;
                case '?':
                    printf(usage);
                    exit(0);
                    break;
                default:
                    error_unknown_switch(chu, s);
                    break;
                }
            }
            s++;
        } else {
            if (ch2 == ':')
            {
                switch (chu)
                {
                case 'L':
                    /* fall through */
                case 'R':
                    s += 2;
                    while (*s && !isspace(*s))
                    {
                        s++;
                    }
                    break;
                default:
                    error_unknown_switch(chu, s);
                    break;
                }
            } else {
                /* this is a file name, starting from '/' */
                s--;
                break;
            }
        }
        /* skip spaces to the next parameter */
        ch = *s;
        while (ch && isspace(ch))
        {
            s++;
            ch = *s;
        }
    }

    if (action == ACTION_UNDEF)
    {
        action = ACTION_ADD;
    }

    switch (action)
    {
    case ACTION_ADD:
    {
        CHAR filename[MAX_PATH];
        FILE *reg_file;

        get_file_name(&s, filename);
        if (!filename[0])
        {
            printf("%s: No file name is specified\n%s", getAppName(), usage);
            exit(1);
        }

        while(filename[0])
        {
            reg_file = fopen(filename, "r");
            if (reg_file)
            {
                processRegLines(reg_file, doSetValue);
            } else {
                perror("");
                printf("%s: Can't open file \"%s\"\n", getAppName(), filename);
                exit(1);
            }
            get_file_name(&s, filename);
        }
        break;
    }
    case ACTION_DELETE:
    {
        CHAR reg_key_name[KEY_MAX_LEN];

        get_file_name(&s, reg_key_name);
        if (!reg_key_name[0])
        {
            printf("%s: No registry key is specified for removal\n%s",
                   getAppName(), usage);
            exit(1);
        }
        delete_registry_key(reg_key_name);
        break;
    }
    case ACTION_EXPORT:
    {
        CHAR filename[MAX_PATH];

        filename[0] = '\0';
        get_file_name(&s, filename);
        if (!filename[0])
        {
            printf("%s: No file name is specified\n%s", getAppName(), usage);
            exit(1);
        }

        if (s[0])
        {
            CHAR reg_key_name[KEY_MAX_LEN];

            get_file_name(&s, reg_key_name);
            export_registry_key(filename, reg_key_name);
        } else {
            export_registry_key(filename, NULL);
        }
        break;
    }
    default:
        printf("%s: Unhandled action!\n", getAppName());
        exit(1);
        break;
    }
    return 0;
}
