/*
 * Unit test suite for lz32 functions
 *
 * Copyright 2004 Evan Parry, Daniel Kegel
 *
 * 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 <stdarg.h>
#include <windef.h>
#include <winbase.h>
#include <stdlib.h>
#include <winerror.h>
#include <lzexpand.h>

#include "wine/test.h"

static char filename_[] = "testfile.xx_";
#if 0
static char filename[] = "testfile.xxx";
#endif
static char filename2[] = "testfile.yyy";

/* This is the hex string representation of the file created by compressing
   a simple text file with the contents "This is a test file."
 
   The file was created using COMPRESS.EXE from the Windows Server 2003
   Resource Kit from Microsoft.  The resource kit was retrieved from the
   following URL:  

   http://www.microsoft.com/downloads/details.aspx?FamilyID=9d467a69-57ff-4ae7-96ee-b18c4790cffd&displaylang=en
 */
static const unsigned char compressed_file[] = 
  {0x53,0x5A,0x44,0x44,0x88,0xF0,0x27,0x33,0x41,
   0x74,0x75,0x14,0x00,0x00,0xDF,0x54,0x68,0x69,
   0x73,0x20,0xF2,0xF0,0x61,0x20,0xFF,0x74,0x65,
   0x73,0x74,0x20,0x66,0x69,0x6C,0x03,0x65,0x2E};
static const DWORD compressed_file_size = sizeof(compressed_file);

static const char uncompressed_data[] = "This is a test file.";
static const DWORD uncompressed_data_size = sizeof(uncompressed_data) - 1;

static char *buf;

static void test_lzopenfile(void)
{
  OFSTRUCT test;
  DWORD retval;
  INT file;

  /* Check for nonexistent file. */
  file = LZOpenFile("badfilename_", &test, OF_READ);
  ok(file == LZERROR_BADINHANDLE, 
     "LZOpenFile succeeded on nonexistent file\n");
  LZClose(file);

  /* Create an empty file. */
  file = LZOpenFile(filename_, &test, OF_CREATE);
  ok(file >= 0, "LZOpenFile failed on creation\n");
  LZClose(file);
  retval = GetFileAttributes(filename_);
  ok(retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributes: error %ld\n", 
     GetLastError());

  /* Check various opening options. */
  file = LZOpenFile(filename_, &test, OF_READ);
  ok(file >= 0, "LZOpenFile failed on read\n");
  LZClose(file);
  file = LZOpenFile(filename_, &test, OF_WRITE);
  ok(file >= 0, "LZOpenFile failed on write\n");
  LZClose(file);
  file = LZOpenFile(filename_, &test, OF_READWRITE);
  ok(file >= 0, "LZOpenFile failed on read/write\n");
  LZClose(file);
  file = LZOpenFile(filename_, &test, OF_EXIST);
  ok(file >= 0, "LZOpenFile failed on read/write\n");
  LZClose(file);


  /* If the file "foo.xxx" does not exist, LZOpenFile should then
     check for the file "foo.xx_" and open that -- at least on some
     operating systems.  Doesn't seem to on my copy of Win98.   
     The Wine testing guidelines say we should accept the behavior of
     any valid version of Windows.  Thus it seems we cannot check this?!
     Revisit this at some point to see if this can be tested somehow.
   */
#if 0
  file = LZOpenFile(filename, &test, OF_EXIST);
  ok(file != LZERROR_BADINHANDLE, 
     "LZOpenFile \"filename_\" check failed\n");
  LZClose(file);
#endif

  /* Delete the file then make sure it doesn't exist anymore. */
  file = LZOpenFile(filename_, &test, OF_DELETE);
  ok(file >= 0, "LZOpenFile failed on delete\n");
  LZClose(file);

  retval = GetFileAttributes(filename_);
  ok(retval == INVALID_FILE_ATTRIBUTES, 
     "GetFileAttributes succeeded on deleted file\n");
  
}

static void test_lzread(void)
{
  HANDLE file;
  DWORD ret;
  int cfile;
  OFSTRUCT test;
  BOOL retok;

  /* Create the compressed file. */
  file = CreateFile(filename_, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0);
  ok(file != INVALID_HANDLE_VALUE, "Could not create test file\n");
  retok = WriteFile(file, compressed_file, compressed_file_size, &ret, 0);
  ok( retok, "WriteFile: error %ld\n", GetLastError());
  ok(ret == compressed_file_size, "Wrote wrong number of bytes with WriteFile?\n");
  CloseHandle(file);

  cfile = LZOpenFile(filename_, &test, OF_READ);
  ok(cfile > 0, "LZOpenFile failed\n");

  ret = LZRead(cfile, buf, uncompressed_data_size);
  ok(ret == uncompressed_data_size, "Read wrong number of bytes\n");

  /* Compare what we read with what we think we should read. */
  ok(memcmp(buf, uncompressed_data, uncompressed_data_size) == 0,
     "buffer contents mismatch\n");

  todo_wine {
     /* Wine returns the number of bytes actually read instead of an error */
     ret = LZRead(cfile, buf, uncompressed_data_size);
     ok(ret == LZERROR_READ, "Expected read-past-EOF to return LZERROR_READ\n");
  }

  LZClose(cfile);

  ret = DeleteFile(filename_);
  ok(ret, "DeleteFile: error %ld\n", GetLastError());
}

static void test_lzcopy(void)
{
  HANDLE file;
  DWORD ret;
  int source, dest;
  OFSTRUCT stest, dtest;
  BOOL retok;

  /* Create the compressed file. */
  file = CreateFile(filename_, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0);
  ok(file != INVALID_HANDLE_VALUE, 
     "CreateFile: error %ld\n", GetLastError());
  retok = WriteFile(file, compressed_file, compressed_file_size, &ret, 0);
  ok( retok, "WriteFile error %ld\n", GetLastError());
  ok(ret == compressed_file_size, "Wrote wrong number of bytes\n");
  CloseHandle(file);

  source = LZOpenFile(filename_, &stest, OF_READ);
  ok(source >= 0, "LZOpenFile failed on compressed file\n");
  dest = LZOpenFile(filename2, &dtest, OF_CREATE);
  ok(dest >= 0, "LZOpenFile failed on creating new file %d\n", dest);

  ret = LZCopy(source, dest);
  ok(ret > 0, "LZCopy error\n");

  LZClose(source);
  LZClose(dest);

  file = CreateFile(filename2, GENERIC_READ, 0, NULL, OPEN_EXISTING,
		    0, 0);
  ok(file != INVALID_HANDLE_VALUE,
     "CreateFile: error %ld\n", GetLastError());

  retok = ReadFile(file, buf, uncompressed_data_size*2, &ret, 0);
  ok( retok && ret == uncompressed_data_size, "ReadFile: error %ld\n", GetLastError());
  /* Compare what we read with what we think we should read. */
  ok(!memcmp(buf, uncompressed_data, uncompressed_data_size),
     "buffer contents mismatch\n");
  CloseHandle(file);

  ret = DeleteFile(filename_);
  ok(ret, "DeleteFile: error %ld\n", GetLastError());
  ret = DeleteFile(filename2);
  ok(ret, "DeleteFile: error %ld\n", GetLastError());
}

START_TEST(lzexpand_main)
{
  buf = malloc(uncompressed_data_size * 2);
  test_lzopenfile();
  test_lzread();
  test_lzcopy();
  free(buf);
}
