#include <windows.h>
#include <stdio.h>
#include <string>
#include "ServiceInstaller.h"
#include "ServiceBase.h"
#include "ANSTSService.h"

// -----------------------------------------------------------------------------
// Service Configuration (UNICODE / std::wstring)
// -----------------------------------------------------------------------------
const std::wstring SERVICE_NAME = L"ANSTSService";
const std::wstring SERVICE_DISPLAY_NAME = L"ANSTS Service";
const DWORD        SERVICE_START_TYPE = SERVICE_AUTO_START;
const std::wstring SERVICE_DEPENDENCIES = L"";
const std::wstring SERVICE_ACCOUNT = L"NT AUTHORITY\\LocalService";
const std::wstring SERVICE_PASSWORD = L"";

bool StopService(const std::wstring& serviceName)
{
    SC_HANDLE schSCManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT);
    if (!schSCManager)
    {
        wprintf(L"OpenSCManager failed (%lu)\n", GetLastError());
        return false;
    }

    SC_HANDLE schService = OpenService(schSCManager, serviceName.c_str(), SERVICE_STOP | SERVICE_QUERY_STATUS);
    if (!schService)
    {
        wprintf(L"OpenService failed (%lu)\n", GetLastError());
        CloseServiceHandle(schSCManager);
        return false;
    }

    SERVICE_STATUS ss;
    if (!ControlService(schService, SERVICE_CONTROL_STOP, &ss))
    {
        wprintf(L"ControlService failed (%lu)\n", GetLastError());
    }
    else
    {
        wprintf(L"Service stop requested...\n");
        Sleep(1000);
    }

    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);
    return true;
}

bool StartServiceByName(const std::wstring& serviceName)
{
    SC_HANDLE schSCManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT);
    if (!schSCManager)
    {
        wprintf(L"OpenSCManager failed (%lu)\n", GetLastError());
        return false;
    }

    SC_HANDLE schService = OpenService(schSCManager, serviceName.c_str(), SERVICE_START);
    if (!schService)
    {
        wprintf(L"OpenService failed (%lu)\n", GetLastError());
        CloseServiceHandle(schSCManager);
        return false;
    }

    if (!StartService(schService, 0, nullptr))
    {
        DWORD error = GetLastError();
        if (error == ERROR_SERVICE_ALREADY_RUNNING)
        {
            wprintf(L"Service is already running.\n");
        }
        else
        {
            wprintf(L"StartService failed (%lu)\n", error);
        }
    }
    else
    {
        wprintf(L"Service start requested.\n");
    }

    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);
    return true;
}

int wmain(int argc, wchar_t* argv[])
{
    if (argc > 1)
    {
        std::wstring arg = argv[1];
        if (arg.size() > 1 && (arg[0] == L'-' || arg[0] == L'/'))
        {
            std::wstring cmd = arg.substr(1);  // remove '-' or '/'

            if (_wcsicmp(cmd.c_str(), L"install") == 0)
            {
                InstallService(
                    SERVICE_NAME,
                    SERVICE_DISPLAY_NAME,
                    SERVICE_START_TYPE,
                    SERVICE_DEPENDENCIES,
                    SERVICE_ACCOUNT,
                    SERVICE_PASSWORD
                );
            }
            else if (_wcsicmp(cmd.c_str(), L"remove") == 0)
            {
                UninstallService(SERVICE_NAME);
            }
            else if (_wcsicmp(cmd.c_str(), L"stop") == 0)
            {
                StopService(SERVICE_NAME);
            }
            else if (_wcsicmp(cmd.c_str(), L"start") == 0)
            {
                StartServiceByName(SERVICE_NAME);
            }
            else
            {
                wprintf(L"Unknown command: %s\n", argv[1]);
                wprintf(L"Usage:\n");
                wprintf(L"  -install    Install the service\n");
                wprintf(L"  -remove     Remove the service\n");
                wprintf(L"  -start      Start the service\n");
                wprintf(L"  -stop       Stop the service\n");
            }
            return 0;
        }
    }

    // No arguments or invalid, run as service
    ANSTSService service(SERVICE_NAME.c_str());
    if (!CServiceBase::Run(service))
    {
        wprintf(L"Service failed to run with error 0x%08lx\n", GetLastError());
    }

    return 0;
}
