/*
 * Copyright 2010 Hans Leidekker
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define WIN32_LEAN_AND_MEAN

#include "wine/debug.h"
#include "wine/unicode.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <winsvc.h>

WINE_DEFAULT_DEBUG_CHANNEL(sc);

struct create_params
{
    const WCHAR *displayname;
    const WCHAR *binpath;
    const WCHAR *group;
    const WCHAR *depend;
    const WCHAR *obj;
    const WCHAR *password;
    DWORD type;
    DWORD start;
    DWORD error;
    BOOL tag;
};

static BOOL parse_create_params( int argc, const WCHAR *argv[], struct create_params *cp )
{
    static const WCHAR displaynameW[] = {'d','i','s','p','l','a','y','n','a','m','e','=',0};
    static const WCHAR typeW[] = {'t','y','p','e','=',0};
    static const WCHAR startW[] = {'s','t','a','r','t','=',0};
    static const WCHAR errorW[] = {'e','r','r','o','r','=',0};
    static const WCHAR binpathW[] = {'b','i','n','p','a','t','h','=',0};
    static const WCHAR groupW[] = {'g','r','o','u','p','=',0};
    static const WCHAR tagW[] = {'t','a','g','=',0};
    static const WCHAR dependW[] = {'d','e','p','e','n','d','=',0};
    static const WCHAR objW[] = {'o','b','j','=',0};
    static const WCHAR passwordW[] = {'p','a','s','s','w','o','r','d','=',0};
    unsigned int i;

    cp->displayname = NULL;
    cp->type        = SERVICE_WIN32_OWN_PROCESS;
    cp->start       = SERVICE_DEMAND_START;
    cp->error       = SERVICE_ERROR_NORMAL;
    cp->binpath     = NULL;
    cp->group       = NULL;
    cp->tag         = FALSE;
    cp->depend      = NULL;
    cp->obj         = NULL;
    cp->password    = NULL;

    for (i = 0; i < argc; i++)
    {
        if (!strcmpiW( argv[i], displaynameW ) && i < argc - 1) cp->displayname = argv[i + 1];
        if (!strcmpiW( argv[i], binpathW ) && i < argc - 1) cp->binpath = argv[i + 1];
        if (!strcmpiW( argv[i], groupW ) && i < argc - 1) cp->group = argv[i + 1];
        if (!strcmpiW( argv[i], dependW ) && i < argc - 1) cp->depend = argv[i + 1];
        if (!strcmpiW( argv[i], objW ) && i < argc - 1) cp->obj = argv[i + 1];
        if (!strcmpiW( argv[i], passwordW ) && i < argc - 1) cp->password = argv[i + 1];

        if (!strcmpiW( argv[i], tagW ) && i < argc - 1)
        {
            static const WCHAR yesW[] = {'y','e','s',0};
            if (!strcmpiW( argv[i], yesW ))
            {
                WINE_FIXME("tag argument not supported\n");
                cp->tag = TRUE;
            }
        }
        if (!strcmpiW( argv[i], typeW ) && i < argc - 1)
        {
            static const WCHAR ownW[] = {'o','w','n',0};
            static const WCHAR shareW[] = {'s','h','a','r','e',0};
            static const WCHAR kernelW[] = {'k','e','r','n','e','l',0};
            static const WCHAR filesysW[] = {'f','i','l','e','s','y','s',0};
            static const WCHAR recW[] = {'r','e','c',0};
            static const WCHAR interactW[] = {'i','n','t','e','r','a','c','t',0};

            if (!strcmpiW( argv[i + 1], ownW )) cp->type = SERVICE_WIN32_OWN_PROCESS;
            if (!strcmpiW( argv[i + 1], shareW )) cp->type = SERVICE_WIN32_SHARE_PROCESS;
            if (!strcmpiW( argv[i + 1], kernelW )) cp->type = SERVICE_KERNEL_DRIVER;
            if (!strcmpiW( argv[i + 1], filesysW )) cp->type = SERVICE_FILE_SYSTEM_DRIVER;
            if (!strcmpiW( argv[i + 1], recW )) cp->type = SERVICE_RECOGNIZER_DRIVER;
            if (!strcmpiW( argv[i + 1], interactW )) cp->type |= SERVICE_INTERACTIVE_PROCESS;
        }
        if (!strcmpiW( argv[i], startW ) && i < argc - 1)
        {
            static const WCHAR bootW[] = {'b','o','o','t',0};
            static const WCHAR systemW[] = {'s','y','s','t','e','m',0};
            static const WCHAR autoW[] = {'a','u','t','o',0};
            static const WCHAR demandW[] = {'d','e','m','a','n','d',0};
            static const WCHAR disabledW[] = {'d','i','s','a','b','l','e','d',0};

            if (!strcmpiW( argv[i + 1], bootW )) cp->start = SERVICE_BOOT_START;
            if (!strcmpiW( argv[i + 1], systemW )) cp->start = SERVICE_SYSTEM_START;
            if (!strcmpiW( argv[i + 1], autoW )) cp->start = SERVICE_AUTO_START;
            if (!strcmpiW( argv[i + 1], demandW )) cp->start = SERVICE_DEMAND_START;
            if (!strcmpiW( argv[i + 1], disabledW )) cp->start = SERVICE_DISABLED;
        }
        if (!strcmpiW( argv[i], errorW ) && i < argc - 1)
        {
            static const WCHAR normalW[] = {'n','o','r','m','a','l',0};
            static const WCHAR severeW[] = {'s','e','v','e','r','e',0};
            static const WCHAR criticalW[] = {'c','r','i','t','i','c','a','l',0};
            static const WCHAR ignoreW[] = {'i','g','n','o','r','e',0};

            if (!strcmpiW( argv[i + 1], normalW )) cp->error = SERVICE_ERROR_NORMAL;
            if (!strcmpiW( argv[i + 1], severeW )) cp->error = SERVICE_ERROR_SEVERE;
            if (!strcmpiW( argv[i + 1], criticalW )) cp->error = SERVICE_ERROR_CRITICAL;
            if (!strcmpiW( argv[i + 1], ignoreW )) cp->error = SERVICE_ERROR_IGNORE;
        }
    }
    if (!cp->binpath) return FALSE;
    return TRUE;
}

static BOOL parse_failure_actions( const WCHAR *arg, SERVICE_FAILURE_ACTIONSW *fa )
{
    static const WCHAR runW[] = {'r','u','n',0};
    static const WCHAR restartW[] = {'r','e','s','t','a','r','t',0};
    static const WCHAR rebootW[] = {'r','e','b','o','o','t',0};
    unsigned int i, count;
    WCHAR *actions, *p;

    actions = HeapAlloc( GetProcessHeap(), 0, (strlenW( arg ) + 1) * sizeof(WCHAR) );
    if (!actions) return FALSE;

    strcpyW( actions, arg );
    for (p = actions, count = 0; *p; p++)
    {
        if (*p == '/')
        {
            count++;
            *p = 0;
        }
    }
    count = count / 2 + 1;

    fa->cActions = count;
    fa->lpsaActions = HeapAlloc( GetProcessHeap(), 0, fa->cActions * sizeof(SC_ACTION) );
    if (!fa->lpsaActions)
    {
        HeapFree( GetProcessHeap(), 0, actions );
        return FALSE;
    }

    p = actions;
    for (i = 0; i < count; i++)
    {
        if (!strcmpiW( p, runW )) fa->lpsaActions[i].Type = SC_ACTION_RUN_COMMAND;
        else if (!strcmpiW( p, restartW )) fa->lpsaActions[i].Type = SC_ACTION_RESTART;
        else if (!strcmpiW( p, rebootW )) fa->lpsaActions[i].Type = SC_ACTION_REBOOT;
        else fa->lpsaActions[i].Type = SC_ACTION_NONE;

        p += strlenW( p ) + 1;
        fa->lpsaActions[i].Delay = atoiW( p );
        p += strlenW( p ) + 1;
    }

    HeapFree( GetProcessHeap(), 0, actions );
    return TRUE;
}

static BOOL parse_failure_params( int argc, const WCHAR *argv[], SERVICE_FAILURE_ACTIONSW *fa )
{
    static const WCHAR resetW[] = {'r','e','s','e','t','=',0};
    static const WCHAR rebootW[] = {'r','e','b','o','o','t','=',0};
    static const WCHAR commandW[] = {'c','o','m','m','a','n','d','=',0};
    static const WCHAR actionsW[] = {'a','c','t','i','o','n','s','=',0};
    unsigned int i;

    fa->dwResetPeriod = 0;
    fa->lpRebootMsg   = NULL;
    fa->lpCommand     = NULL;
    fa->cActions      = 0;
    fa->lpsaActions   = NULL;

    for (i = 0; i < argc; i++)
    {
        if (!strcmpiW( argv[i], resetW ) && i < argc - 1) fa->dwResetPeriod = atoiW( argv[i + 1] );
        if (!strcmpiW( argv[i], rebootW ) && i < argc - 1) fa->lpRebootMsg = (WCHAR *)argv[i + 1];
        if (!strcmpiW( argv[i], commandW ) && i < argc - 1) fa->lpCommand = (WCHAR *)argv[i + 1];
        if (!strcmpiW( argv[i], actionsW ))
        {
            if (i == argc - 1) return FALSE;
            if (!parse_failure_actions( argv[i + 1], fa )) return FALSE;
        }
    }
    return TRUE;
}

static void usage( void )
{
    WINE_MESSAGE( "Usage: sc command servicename [parameter= value ...]\n" );
    exit( 1 );
}

int wmain( int argc, const WCHAR *argv[] )
{
    static const WCHAR createW[] = {'c','r','e','a','t','e',0};
    static const WCHAR descriptionW[] = {'d','e','s','c','r','i','p','t','i','o','n',0};
    static const WCHAR failureW[] = {'f','a','i','l','u','r','e',0};
    static const WCHAR deleteW[] = {'d','e','l','e','t','e',0};
    static const WCHAR startW[] = {'s','t','a','r','t',0};
    static const WCHAR stopW[] = {'s','t','o','p',0};
    SC_HANDLE manager, service;
    SERVICE_STATUS status;
    BOOL ret = FALSE;

    if (argc < 3) usage();

    if (argv[2][0] == '\\' && argv[2][1] == '\\')
    {
        WINE_FIXME("server argument not supported\n");
        return 1;
    }

    manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ALL_ACCESS );
    if (!manager)
    {
        WINE_ERR("failed to open service manager\n");
        return 1;
    }

    if (!strcmpiW( argv[1], createW ))
    {
        struct create_params cp;

        if (argc < 4)
        {
            CloseServiceHandle( manager );
            usage();
        }
        if (!parse_create_params( argc - 3, argv + 3, &cp ))
        {
            WINE_WARN("failed to parse create parameters\n");
            CloseServiceHandle( manager );
            return 1;
        }
        service = CreateServiceW( manager, argv[2], cp.displayname, SERVICE_ALL_ACCESS,
                                  cp.type, cp.start, cp.error, cp.binpath, cp.group, NULL,
                                  cp.depend, cp.obj, cp.password );
        if (service)
        {
            CloseServiceHandle( service );
            ret = TRUE;
        }
        else WINE_TRACE("failed to create service %u\n", GetLastError());
    }
    else if (!strcmpiW( argv[1], descriptionW ))
    {
        service = OpenServiceW( manager, argv[2], SERVICE_CHANGE_CONFIG );
        if (service)
        {
            SERVICE_DESCRIPTIONW sd;
            sd.lpDescription = argc > 3 ? (WCHAR *)argv[3] : NULL;
            ret = ChangeServiceConfig2W( service, SERVICE_CONFIG_DESCRIPTION, &sd );
            if (!ret) WINE_TRACE("failed to set service description %u\n", GetLastError());
            CloseServiceHandle( service );
        }
        else WINE_TRACE("failed to open service %u\n", GetLastError());
    }
    else if (!strcmpiW( argv[1], failureW ))
    {
        service = OpenServiceW( manager, argv[2], SERVICE_CHANGE_CONFIG );
        if (service)
        {
            SERVICE_FAILURE_ACTIONSW sfa;
            if (parse_failure_params( argc - 3, argv + 3, &sfa ))
            {
                ret = ChangeServiceConfig2W( service, SERVICE_CONFIG_FAILURE_ACTIONS, &sfa );
                if (!ret) WINE_TRACE("failed to set service failure actions %u\n", GetLastError());
                HeapFree( GetProcessHeap(), 0, sfa.lpsaActions );
            }
            else
                WINE_WARN("failed to parse failure parameters\n");
            CloseServiceHandle( service );
        }
        else WINE_TRACE("failed to open service %u\n", GetLastError());
    }
    else if (!strcmpiW( argv[1], deleteW ))
    {
        service = OpenServiceW( manager, argv[2], DELETE );
        if (service)
        {
            ret = DeleteService( service );
            if (!ret) WINE_TRACE("failed to delete service %u\n", GetLastError());
            CloseServiceHandle( service );
        }
        else WINE_TRACE("failed to open service %u\n", GetLastError());
    }
    else if (!strcmpiW( argv[1], startW ))
    {
        service = OpenServiceW( manager, argv[2], SERVICE_START );
        if (service)
        {
            ret = StartServiceW( service, argc - 3, argv + 3 );
            if (!ret) WINE_TRACE("failed to start service %u\n", GetLastError());
            CloseServiceHandle( service );
        }
        else WINE_TRACE("failed to open service %u\n", GetLastError());
    }
    else if (!strcmpiW( argv[1], stopW ))
    {
        service = OpenServiceW( manager, argv[2], SERVICE_STOP );
        if (service)
        {
            ret = ControlService( service, SERVICE_CONTROL_STOP, &status );
            if (!ret) WINE_TRACE("failed to stop service %u\n", GetLastError());
            CloseServiceHandle( service );
        }
        else WINE_TRACE("failed to open service %u\n", GetLastError());
    }
    else
        WINE_FIXME("command not supported\n");

    CloseServiceHandle( manager );
    return !ret;
}
