/*
 * DxDiag Implementation
 *
 * Copyright 2009 Austin English
 *
 * 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 <windows.h>
#include <dxdiag.h>

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

#include "dxdiag_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(dxdiag);

HINSTANCE hInstance;

struct command_line_info
{
    WCHAR outfile[MAX_PATH];
    enum output_type output_type;
    BOOL whql_check;
};

static void usage(void)
{
    WCHAR title[MAX_STRING_LEN];
    WCHAR usage[MAX_STRING_LEN];

    LoadStringW(hInstance, STRING_DXDIAG_TOOL, title, sizeof(title)/sizeof(WCHAR));
    LoadStringW(hInstance, STRING_USAGE, usage, sizeof(usage)/sizeof(WCHAR));

    MessageBoxW(NULL, usage, title, MB_OK | MB_ICONWARNING);

    ExitProcess(0);
}

static BOOL process_file_name(const WCHAR *cmdline, enum output_type output_type, WCHAR *filename, size_t filename_len)
{
    const WCHAR *endptr;
    size_t len;

    /* Skip any intervening spaces. */
    while (*cmdline == ' ')
        cmdline++;

    /* Ignore filename quoting, if any. */
    if (*cmdline == '"' && (endptr = strrchrW(cmdline, '"')))
    {
        /* Reject a string with only one quote. */
        if (cmdline == endptr)
            return FALSE;

        cmdline++;
    }
    else
        endptr = cmdline + strlenW(cmdline);

    len = endptr - cmdline;
    if (len == 0 || len >= filename_len)
        return FALSE;

    memcpy(filename, cmdline, len * sizeof(WCHAR));
    filename[len] = '\0';

    /* Append an extension appropriate for the output type if the filename does not have one. */
    if (!strrchrW(filename, '.'))
    {
        const WCHAR *filename_ext = get_output_extension(output_type);

        if (len + strlenW(filename_ext) >= filename_len)
            return FALSE;

        strcatW(filename, filename_ext);
    }

    return TRUE;
}

/*
    Process options [/WHQL:ON|OFF][/X outfile|/T outfile]
    Returns TRUE if options were present, FALSE otherwise
    Only one of /X and /T is allowed, /WHQL must come before /X and /T,
    and the rest of the command line after /X or /T is interpreted as a
    filename. If a non-option portion of the command line is encountered,
    dxdiag assumes that the string is a filename for the /T option.

    Native does not interpret quotes, but quotes are parsed here because of how
    Wine handles the command line.
*/

static BOOL process_command_line(const WCHAR *cmdline, struct command_line_info *info)
{
    static const WCHAR whql_colonW[] = {'w','h','q','l',':',0};
    static const WCHAR offW[] = {'o','f','f',0};
    static const WCHAR onW[] = {'o','n',0};

    info->whql_check = FALSE;
    info->output_type = OUTPUT_NONE;

    while (*cmdline)
    {
        /* Skip whitespace before arg */
        while (*cmdline == ' ')
            cmdline++;

        /* If no option is specified, treat the command line as a filename. */
        if (*cmdline != '-' && *cmdline != '/')
        {
            info->output_type = OUTPUT_TEXT;
            return process_file_name(cmdline, OUTPUT_TEXT, info->outfile,
                                     sizeof(info->outfile)/sizeof(WCHAR));
        }

        cmdline++;

        switch (*cmdline)
        {
        case 'T':
        case 't':
            info->output_type = OUTPUT_TEXT;
            return process_file_name(cmdline + 1, OUTPUT_TEXT, info->outfile,
                                     sizeof(info->outfile)/sizeof(WCHAR));
        case 'X':
        case 'x':
            info->output_type = OUTPUT_XML;
            return process_file_name(cmdline + 1, OUTPUT_XML, info->outfile,
                                     sizeof(info->outfile)/sizeof(WCHAR));
        case 'W':
        case 'w':
            if (strncmpiW(cmdline, whql_colonW, 5))
                return FALSE;

            cmdline += 5;

            if (!strncmpiW(cmdline, offW, 3))
            {
                info->whql_check = FALSE;
                cmdline += 2;
            }
            else if (!strncmpiW(cmdline, onW, 2))
            {
                info->whql_check = TRUE;
                cmdline++;
            }
            else
                return FALSE;

            break;
        default:
            return FALSE;
        }

        cmdline++;
    }

    return TRUE;
}

int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR cmdline, int cmdshow)
{
    struct command_line_info info;
    struct dxdiag_information *dxdiag_info;

    hInstance = hInst;

    if (!process_command_line(cmdline, &info))
        usage();

    WINE_TRACE("WHQL check: %s\n", info.whql_check ? "TRUE" : "FALSE");
    WINE_TRACE("Output type: %d\n", info.output_type);
    if (info.output_type != OUTPUT_NONE)
        WINE_TRACE("Output filename: %s\n", debugstr_output_type(info.output_type));

    CoInitialize(NULL);

    dxdiag_info = collect_dxdiag_information(info.whql_check);
    if (!dxdiag_info)
    {
        WINE_ERR("DxDiag information collection failed\n");
        CoUninitialize();
        return 1;
    }

    if (info.output_type != OUTPUT_NONE)
        output_dxdiag_information(dxdiag_info, info.outfile, info.output_type);
    else
        WINE_FIXME("Information dialog is not implemented\n");

    free_dxdiag_information(dxdiag_info);

    CoUninitialize();
    return 0;
}
