/*
 * ATTRIB - Wine-compatible attrib program
 *
 * Copyright 2010-2012 Christian Costa
 *
 * 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
 */

#include <windows.h>
#include <wine/debug.h>
#include <wine/unicode.h>
#include "attrib.h"

WINE_DEFAULT_DEBUG_CHANNEL(attrib);

static const WCHAR starW[]  = {'*','\0'};

/* =========================================================================
 * Load a string from the resource file, handling any error
 * Returns string retrieved from resource file
 * ========================================================================= */
static WCHAR *ATTRIB_LoadMessage(UINT id)
{
    static WCHAR msg[MAXSTRING];
    const WCHAR failedMsg[]  = {'F', 'a', 'i', 'l', 'e', 'd', '!', 0};

    if (!LoadStringW(GetModuleHandleW(NULL), id, msg, sizeof(msg)/sizeof(WCHAR))) {
        WINE_FIXME("LoadString failed with %d\n", GetLastError());
        lstrcpyW(msg, failedMsg);
    }
    return msg;
}

/* =========================================================================
 * Output a formatted unicode string. Ideally this will go to the console
 *  and hence required WriteConsoleW to output it, however if file i/o is
 *  redirected, it needs to be WriteFile'd using OEM (not ANSI) format
 * ========================================================================= */
static int __cdecl ATTRIB_wprintf(const WCHAR *format, ...)
{
    static WCHAR *output_bufW = NULL;
    static char  *output_bufA = NULL;
    static BOOL  toConsole    = TRUE;
    static BOOL  traceOutput  = FALSE;
#define MAX_WRITECONSOLE_SIZE 65535

    __ms_va_list parms;
    DWORD   nOut;
    int len;
    DWORD   res = 0;

    /*
     * Allocate buffer to use when writing to console
     * Note: Not freed - memory will be allocated once and released when
     *         xcopy ends
     */

    if (!output_bufW) output_bufW = HeapAlloc(GetProcessHeap(), 0,
                                              MAX_WRITECONSOLE_SIZE*sizeof(WCHAR));
    if (!output_bufW) {
        WINE_FIXME("Out of memory - could not allocate 2 x 64 KB buffers\n");
        return 0;
    }

    __ms_va_start(parms, format);
    SetLastError(NO_ERROR);
    len = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, format, 0, 0, output_bufW,
                   MAX_WRITECONSOLE_SIZE/sizeof(*output_bufW), &parms);
    __ms_va_end(parms);
    if (len == 0 && GetLastError() != NO_ERROR) {
        WINE_FIXME("Could not format string: le=%u, fmt=%s\n", GetLastError(), wine_dbgstr_w(format));
        return 0;
    }

    /* Try to write as unicode all the time we think it's a console */
    if (toConsole) {
        res = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),
                            output_bufW, len, &nOut, NULL);
    }

    /* If writing to console has failed (ever) we assume it's file
       i/o so convert to OEM codepage and output                  */
    if (!res) {
        BOOL usedDefaultChar = FALSE;
        DWORD convertedChars;

        toConsole = FALSE;

        /*
         * Allocate buffer to use when writing to file. Not freed, as above
         */
        if (!output_bufA) output_bufA = HeapAlloc(GetProcessHeap(), 0,
                                                MAX_WRITECONSOLE_SIZE);
        if (!output_bufA) {
          WINE_FIXME("Out of memory - could not allocate 2 x 64 KB buffers\n");
          return 0;
        }

        /* Convert to OEM, then output */
        convertedChars = WideCharToMultiByte(GetConsoleOutputCP(), 0, output_bufW,
                            len, output_bufA, MAX_WRITECONSOLE_SIZE,
                            "?", &usedDefaultChar);
        WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), output_bufA, convertedChars,
                  &nOut, FALSE);
    }

    /* Trace whether screen or console */
    if (!traceOutput) {
        WINE_TRACE("Writing to console? (%d)\n", toConsole);
        traceOutput = TRUE;
    }
    return nOut;
}

/* =========================================================================
 * Handle the processing for a single directory, optionally recursing into
 *  subdirectories if needed.
 * Parameters:
 *  rootdir      [I]   The directory to search in
 *  filespec     [I]   The filespec to search for
 *  recurse      [I]   Whether to recurse (search subdirectories before
 *                          current directory)
 *  includedirs  [I]   Whether to set directory attributes as well
 *  attrib_set   [I]   Attributes to set
 *  attrib_clear [I]   Attributes to clear
 *
 * Returns TRUE if at least one file displayed / modified
 * ========================================================================= */
static BOOL ATTRIB_processdirectory(const WCHAR *rootdir, const WCHAR *filespec,
                                    BOOL recurse, BOOL includedirs,
                                    DWORD attrib_set, DWORD attrib_clear)
{
    BOOL found = FALSE;
    WCHAR buffer[MAX_PATH];
    HANDLE hff;
    WIN32_FIND_DATAW fd;
    WCHAR flags[] = {' ',' ',' ',' ',' ',' ',' ',' ','\0'};
    static const WCHAR slashW[] = {'\\','\0'};

    WINE_TRACE("Processing dir '%s', spec '%s', %d,%x,%x\n",
               wine_dbgstr_w(rootdir), wine_dbgstr_w(filespec),
               recurse, attrib_set, attrib_clear);

    if (recurse) {

      /* Build spec to search for */
      strcpyW(buffer, rootdir);
      strcatW(buffer, starW);

      /* Search for directories in the location and recurse if necessary */
      WINE_TRACE("Searching for directories with '%s'\n", wine_dbgstr_w(buffer));
      hff = FindFirstFileW(buffer, &fd);
      if (hff != INVALID_HANDLE_VALUE) {
          do {
              const WCHAR dot[] = {'.', 0};
              const WCHAR dotdot[] = {'.', '.', 0};

              /* Only interested in directories, and not . nor .. */
              if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
                  !strcmpW(fd.cFileName, dot) || !strcmpW(fd.cFileName, dotdot))
                  continue;

              /* Build new root dir to go searching in */
              strcpyW(buffer, rootdir);
              strcatW(buffer, fd.cFileName);
              strcatW(buffer, slashW);
              ATTRIB_processdirectory(buffer, filespec, recurse, includedirs,
                                      attrib_set, attrib_clear);

          } while (FindNextFileW(hff, &fd) != 0);
      }
      FindClose (hff);
    }

    /* Build spec to search for */
    strcpyW(buffer, rootdir);
    strcatW(buffer, filespec);
    WINE_TRACE("Searching for files as '%s'\n", wine_dbgstr_w(buffer));

    /* Search for files in the location with the filespec supplied */
    hff = FindFirstFileW(buffer, &fd);
    if (hff != INVALID_HANDLE_VALUE) {
        do {
            const WCHAR dot[] = {'.', 0};
            const WCHAR dotdot[] = {'.', '.', 0};
            DWORD count;
            WINE_TRACE("Found '%s'\n", wine_dbgstr_w(fd.cFileName));

            if (!strcmpW(fd.cFileName, dot) || !strcmpW(fd.cFileName, dotdot))
                continue;

            if (!includedirs && (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
              continue;

            if (attrib_set || attrib_clear) {
                fd.dwFileAttributes &= ~attrib_clear;
                fd.dwFileAttributes |= attrib_set;
                if (!fd.dwFileAttributes)
                    fd.dwFileAttributes |= FILE_ATTRIBUTE_NORMAL;
                strcpyW(buffer, rootdir);
                strcatW(buffer, fd.cFileName);
                SetFileAttributesW(buffer, fd.dwFileAttributes);
                found = TRUE;
            } else {
                static const WCHAR fmt[] = {'%','1',' ',' ',' ',' ',' ','%','2','\n','\0'};
                if (fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {
                    flags[4] = 'H';
                }
                if (fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) {
                    flags[1] = 'S';
                }
                if (fd.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) {
                    flags[0] = 'A';
                }
                if (fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
                    flags[5] = 'R';
                }
                if (fd.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) {
                    flags[6] = 'T';
                }
                if (fd.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) {
                    flags[7] = 'C';
                }
                strcpyW(buffer, rootdir);
                strcatW(buffer, fd.cFileName);
                ATTRIB_wprintf(fmt, flags, buffer);
                for (count = 0; count < (sizeof(flags)/sizeof(WCHAR) - 1); count++) flags[count] = ' ';
                found = TRUE;
            }
        } while (FindNextFileW(hff, &fd) != 0);
    }
    FindClose (hff);
    return found;
}

int wmain(int argc, WCHAR *argv[])
{
    WCHAR name[MAX_PATH];
    WCHAR *namepart;
    WCHAR curdir[MAX_PATH];
    WCHAR originalname[MAX_PATH];
    DWORD attrib_set = 0;
    DWORD attrib_clear = 0;
    BOOL  attrib_recurse = FALSE;
    BOOL  attrib_includedirs = FALSE;
    static const WCHAR help_option[] = {'/','?','\0'};
    static const WCHAR wildcardsW[] = {'*','?','\0'};
    int i = 1;
    BOOL  found = FALSE;

    if ((argc >= 2) && !strcmpW(argv[1], help_option)) {
        ATTRIB_wprintf(ATTRIB_LoadMessage(STRING_HELP));
        return 0;
    }

    /* By default all files from current directory are taken into account */
    strcpyW(name, starW);

    while (i < argc) {
        WCHAR *param = argv[i++];
        WINE_TRACE("Processing arg: '%s'\n", wine_dbgstr_w(param));
        if ((param[0] == '+') || (param[0] == '-')) {
            DWORD attrib = 0;
            switch (param[1]) {
            case 'H': case 'h': attrib |= FILE_ATTRIBUTE_HIDDEN; break;
            case 'S': case 's': attrib |= FILE_ATTRIBUTE_SYSTEM; break;
            case 'R': case 'r': attrib |= FILE_ATTRIBUTE_READONLY; break;
            case 'A': case 'a': attrib |= FILE_ATTRIBUTE_ARCHIVE; break;
            default:
                ATTRIB_wprintf(ATTRIB_LoadMessage(STRING_NYI));
                return 0;
            }
            switch (param[0]) {
            case '+': attrib_set = attrib; break;
            case '-': attrib_clear = attrib; break;
            }
        } else if (param[0] == '/') {
            if (((param[1] == 'D') || (param[1] == 'd')) && !param[2]) {
                attrib_includedirs = TRUE;
            } else if (((param[1] == 'S') || (param[1] == 's')) && !param[2]) {
                attrib_recurse = TRUE;
            } else {
                WINE_FIXME("Unknown option %s\n", debugstr_w(param));
            }
        } else if (param[0]) {
            strcpyW(originalname, param);
        }
    }

    /* Name may be a relative or explicit path, so calculate curdir based on
       current locations, stripping off the filename                         */
    WINE_TRACE("Supplied name: '%s'\n", wine_dbgstr_w(originalname));
    GetFullPathNameW(originalname, sizeof(curdir)/sizeof(WCHAR), curdir, &namepart);
    WINE_TRACE("Result: '%s'\n", wine_dbgstr_w(curdir));
    if (namepart) {
        strcpyW(name, namepart);
        *namepart = 0;
    } else {
        name[0] = 0;
    }

    /* If a directory is explicitly supplied on the command line, and no
       wildcards are in the name, then allow it to be changed/displayed  */
    if (strpbrkW(originalname, wildcardsW) == NULL) attrib_includedirs = TRUE;

    /* Do all the processing based on the filename arg */
    found = ATTRIB_processdirectory(curdir, name, attrib_recurse,
                                    attrib_includedirs, attrib_set, attrib_clear);
    if (!found) {
      ATTRIB_wprintf(ATTRIB_LoadMessage(STRING_FILENOTFOUND), originalname);
    }
    return 0;
}
