/*
 * Initialization-File Functions.
 *
 * Copyright (c) 1993 Miguel de Icaza
 *
 * 1/Dec o Corrected return values for Get*ProfileString
 *
 *       o Now, if AppName == NULL in Get*ProfileString it returns a list
 *            of the KeyNames (as documented in the MS-SDK).
 *
 *       o if KeyValue == NULL now clears the value in Get*ProfileString
 *
 * 20/Apr  SL - I'm not sure where these definitions came from, but my SDK
 *         has a NULL KeyValue returning a list of KeyNames, and a NULL
 *         AppName undefined.  I changed GetSetProfile to match.  This makes
 *         PROGMAN.EXE do the right thing.
 *
static char Copyright [] = "Copyright (C) 1993 Miguel de Icaza";
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "wine.h"
#include "windows.h"
#include "dos_fs.h"
#include "module.h"
#include "toolhelp.h"
#include "stddebug.h"
/* #define DEBUG_PROFILE */
#include "debug.h"
#include "xmalloc.h"

#define STRSIZE 255
#define overflow (next == &CharBuffer [STRSIZE-1])

typedef struct TKeys {
    char *KeyName;
    char *Value;
    struct TKeys *link;
} TKeys;

typedef struct TSecHeader {
    char *AppName;
    TKeys *Keys;
    struct TSecHeader *link;
} TSecHeader;
    
typedef struct TProfile {
    char *FileName;
    char *FullName;
    TSecHeader *Section;
    struct TProfile *link;
    int changed;
} TProfile;

TProfile *Current = 0;
TProfile *Base = 0;

static TSecHeader *is_loaded (char *FileName)
{
    TProfile *p = Base;
    
    while (p){
	if (!strcasecmp (FileName, p->FileName)){
	    Current = p;
	    return p->Section;
	}
	p = p->link;
    }
    return 0;
}

static char *GetIniFileName(char *name, char *dir)
{
	char temp[256];

	if (strchr(name, '/'))
		return name;

	if (strchr(name, '\\'))
		return DOS_GetUnixFileName(name);

        strcpy(temp, dir);
        strcat(temp, "\\");
	strcat(temp, name);
	
	return DOS_GetUnixFileName(temp);
}

static TSecHeader *load (char *filename, char **pfullname)
{
    FILE *f;
    TSecHeader *SecHeader = 0;
    char CharBuffer [STRSIZE];
    char *bufptr;
    char *lastnonspc;
    int bufsize;
    char *file;
    int c;
    char path[MAX_PATH+1];
    BOOL firstbrace;
    
    *pfullname = NULL;

    /* Try the Windows directory */

    GetWindowsDirectory(path, sizeof(path));
    file = GetIniFileName(filename, path);

    dprintf_profile(stddeb,"Load %s\n", file);
    f = fopen(file, "r");
    
    if (f == NULL) {
	/* Try the path of the current executable */
    
	if (GetCurrentTask())
	{
	    char *p;
	    GetModuleFileName( GetCurrentTask(), path, MAX_PATH );
	    if ((p = strrchr( path, '\\' )))
	    {
		p[1] = '\0';
		file = GetIniFileName(filename, path);
		f = fopen(file, "r");
	    }
	}
    }
    if (f == NULL) {
	fprintf(stderr, "profile.c: load() can't find file %s\n", filename);
        /* FIXME: we ought to create it now (in which directory?) */
	return NULL;
    }
    
    *pfullname = strdup(file);
    dprintf_profile(stddeb,"Loading %s\n", file);

    firstbrace = TRUE;
    for(;;) {	
	c = fgetc(f);
	if (c == EOF) goto finished;
	
	if (isspace(c))
	    continue;
	
	if (c == '[') {
	    TSecHeader *temp = SecHeader;
	    
	    SecHeader = (TSecHeader *) xmalloc (sizeof (TSecHeader));
	    SecHeader->link = temp;
	    SecHeader->Keys = NULL;
	    do {
		c = fgetc(f);
		if (c == EOF) goto bad_file;
	    } while (isspace(c));
	    bufptr = lastnonspc = CharBuffer;
	    bufsize = 0;
	    do {
		if (c != ']') {
		    bufsize++;
		    *bufptr++ = c;
		    if (!isspace(c))
		    	lastnonspc = bufptr;
		} else
		    break;
		c = fgetc(f);
		if (c == EOF) goto bad_file;
	    } while(bufsize < STRSIZE-1);
	    *lastnonspc = 0;
	    if (!strlen(CharBuffer))
	    	fprintf(stderr, "warning: empty section name in ini file\n");
	    SecHeader->AppName = strdup (CharBuffer);
	    dprintf_profile(stddeb,"%s: section %s\n", file, CharBuffer);
	    firstbrace = FALSE;
	} else if (SecHeader) {
	    TKeys *temp = SecHeader->Keys;
	    BOOL skipspc;
	    
	    if (firstbrace)
	    	goto bad_file;
	    bufptr = lastnonspc = CharBuffer;
	    bufsize = 0;
	    do {
		if (c != '=') {
		    bufsize++;
		    *bufptr++ = c;
		    if (!isspace(c))
		    	lastnonspc = bufptr;
		} else
		    break;
		c = fgetc(f);
		if (c == EOF) goto bad_file;
	    } while(bufsize < STRSIZE-1);
	    *lastnonspc = 0;
	    if (!strlen(CharBuffer))
	    	fprintf(stderr, "warning: empty key name in ini file\n");
	    SecHeader->Keys = (TKeys *) xmalloc (sizeof (TKeys));
	    SecHeader->Keys->link = temp;
	    SecHeader->Keys->KeyName = strdup (CharBuffer);

	    dprintf_profile(stddeb,"%s:   key %s\n", file, CharBuffer);
	    
	    bufptr = lastnonspc = CharBuffer;
	    bufsize = 0;
	    skipspc = TRUE;
	    do {
		c = fgetc(f);
		if (c == EOF) break;
		if (c != '\n') {
		    if (!isspace(c) || !skipspc) {
			skipspc = FALSE;
			bufsize++;
			*bufptr++ = c;
			if (!isspace(c))
		    	    lastnonspc = bufptr;
		    }
		} else
		    break;
	    } while(bufsize < STRSIZE-1);
	    *lastnonspc = 0;
	    SecHeader->Keys->Value = strdup (CharBuffer);
	    dprintf_profile (stddeb, "[%s] (%s)=%s\n", SecHeader->AppName,
			     SecHeader->Keys->KeyName, SecHeader->Keys->Value);
	    
	}

    }
bad_file:
    fprintf(stderr, "warning: bad ini file\n");
finished:
    return SecHeader;
}

static void new_key (TSecHeader *section, char *KeyName, char *Value)
{
    TKeys *key;
    
    key = (TKeys *) xmalloc (sizeof (TKeys));
    key->KeyName = strdup (KeyName);
    key->Value   = strdup (Value);
    key->link = section->Keys;
    section->Keys = key;
}

static short GetSetProfile (int set, LPSTR AppName, LPSTR KeyName,
		     LPSTR Default, LPSTR ReturnedString, short Size,
		     LPSTR FileName)

{
    TProfile   *New;
    TSecHeader *section;
    TKeys      *key;
    
    /* Supposedly Default should NEVER be NULL.  But sometimes it is.  */
    if (Default == NULL)
	Default = "";

    if (!(section = is_loaded (FileName))){
	New = (TProfile *) xmalloc (sizeof (TProfile));
	New->link = Base;
	New->FileName = strdup (FileName);
	New->Section = load (FileName, &New->FullName);
	New->changed = FALSE;
	Base = New;
	section = New->Section;
	Current = New;
    }
    /* Start search */
    for (; section; section = section->link){
	if (strcasecmp (section->AppName, AppName))
	    continue;

	/* If no key value given, then list all the keys */
	if ((!KeyName) && (!set)){
	    char *p = ReturnedString;
	    int left = Size - 2;
	    int slen;

	    dprintf_profile(stddeb,"GetSetProfile // KeyName == NULL, Enumeration !\n");
	    for (key = section->Keys; key; key = key->link){
		if (left < 1) {
			dprintf_profile(stddeb,"GetSetProfile // No more storage for enum !\n");
			return (Size - 2);
		}
		slen = MIN(strlen(key->KeyName) + 1, left);
		dprintf_profile(stddeb,"GetSetProfile // strncpy(%p, %p, %d);\n", 
				ReturnedString, key->Value, slen);
		strncpy (p, key->KeyName, slen);
		dprintf_profile(stddeb,"GetSetProfile // enum '%s' !\n", p);
		left -= slen;
		p += slen;
	    }
		*p = '\0';
		dprintf_profile(stddeb,"GetSetProfile // normal end of enum !\n");
	    return (Size - 2 - left);
	}
	for (key = section->Keys; key; key = key->link){
	    int slen;
	    if (strcasecmp (key->KeyName, KeyName))
		continue;
	    if (set){
		free (key->Value);
		key->Value = strdup (Default ? Default : "");
		Current->changed=TRUE;
		return 1;
	    }
	    slen = MIN(strlen(key->Value), Size - 1);
	    ReturnedString[slen] = 0;
	    strncpy (ReturnedString, key->Value, slen);
	    dprintf_profile(stddeb,"GetSetProfile // Return ``%s''\n", ReturnedString);
	    return 1; 
	}
	/* If Getting the information, then don't write the information
	   to the INI file, need to run a couple of tests with windog */
	/* No key found */
	if (set) {
	    new_key (section, KeyName, Default);
        } else {
	    int slen = MIN(strlen(Default), Size - 1);
            ReturnedString[slen] = 0;
            strncpy(ReturnedString, Default, slen);
	    dprintf_profile(stddeb,"GetSetProfile // Key not found\n");
	}
	return 1;
    }
    /* Non existent section */
    if (set){
	section = (TSecHeader *) xmalloc (sizeof (TSecHeader));
	section->AppName = strdup (AppName);
	section->Keys = 0;
	new_key (section, KeyName, Default);
	section->link = Current->Section;
	Current->Section = section;
	Current->changed = TRUE;
    } else {
	int slen = MIN(strlen(Default), Size - 1);
	ReturnedString[slen] = 0;
	strncpy(ReturnedString, Default, slen);
	dprintf_profile(stddeb,"GetSetProfile // Section not found\n");
    }
    return 1;
}

short GetPrivateProfileString (LPSTR AppName, LPSTR KeyName,
			       LPSTR Default, LPSTR ReturnedString,
			       short Size, LPSTR FileName)
{
    int v;

    dprintf_profile(stddeb,"GetPrivateProfileString ('%s', '%s', '%s', %p, %d, %s\n", 
			AppName, KeyName, Default, ReturnedString, Size, FileName);
    v = GetSetProfile (0,AppName,KeyName,Default,ReturnedString,Size,FileName);
    if (AppName)
	return strlen (ReturnedString);
    else
	return Size - v;
}

int GetProfileString (LPSTR AppName, LPSTR KeyName, LPSTR Default, 
		      LPSTR ReturnedString, int Size)
{
    return GetPrivateProfileString (AppName, KeyName, Default,
				    ReturnedString, Size, WIN_INI);
}

WORD GetPrivateProfileInt (LPSTR AppName, LPSTR KeyName, short Default,
			   LPSTR File)
{
    static char IntBuf[10];
    static char buf[10];

    sprintf (buf, "%d", Default);
    
    /* Check the exact semantic with the SDK */
    GetPrivateProfileString (AppName, KeyName, buf, IntBuf, 10, File);
    if (!strcasecmp (IntBuf, "true"))
	return 1;
    if (!strcasecmp (IntBuf, "yes"))
	return 1;
    return strtoul( IntBuf, NULL, 0 );
}

WORD GetProfileInt (LPSTR AppName, LPSTR KeyName, int Default)
{
    return GetPrivateProfileInt (AppName, KeyName, Default, WIN_INI);
}

BOOL WritePrivateProfileString (LPSTR AppName, LPSTR KeyName, LPSTR String,
				LPSTR FileName)
{
    if (!AppName || !KeyName || !String)  /* Flush file to disk */
        return TRUE;
    return GetSetProfile (1, AppName, KeyName, String, "", 0, FileName);
}

BOOL WriteProfileString (LPSTR AppName, LPSTR KeyName, LPSTR String)
{
    return (WritePrivateProfileString (AppName, KeyName, String, WIN_INI));
}

static void dump_keys (FILE *profile, TKeys *p)
{
    if (!p)
	return;
    dump_keys (profile, p->link);
    fprintf (profile, "%s=%s\r\n", p->KeyName, p->Value);
}

static void dump_sections (FILE *profile, TSecHeader *p)
{
    if (!p)
	return;
    dump_sections (profile, p->link);
    fprintf (profile, "\r\n[%s]\r\n", p->AppName);
    dump_keys (profile, p->Keys);
}

static void dump_profile (TProfile *p)
{
    FILE *profile;
    
    if (!p)
	return;
    dump_profile (p->link);
    if(!p->changed)
	return;
    if (p->FullName && (profile = fopen (p->FullName, "w")) != NULL){
	dump_sections (profile, p->Section);
	fclose (profile);
    }
}

void sync_profiles (void)
{
    dump_profile (Base);
}
