/*
 * The freedesktop.org Trash, implemented using the 0.7 spec version
 * (see http://www.ramendik.ru/docs/trashspec.html)
 *
 * Copyright (C) 2006 Mikolaj Zalewski
 *
 * 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 "config.h"

#include <stdarg.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#include <sys/types.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_DIRENT_H
# include <dirent.h>
#endif

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winreg.h"
#include "shlwapi.h"
#include "winternl.h"

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>
#include "wine/debug.h"
#include "shell32_main.h"
#include "xdg.h"

WINE_DEFAULT_DEBUG_CHANNEL(trash);

static CRITICAL_SECTION TRASH_Creating;
static CRITICAL_SECTION_DEBUG TRASH_Creating_Debug =
{
    0, 0, &TRASH_Creating,
    { &TRASH_Creating_Debug.ProcessLocksList,
      &TRASH_Creating_Debug.ProcessLocksList},
    0, 0, { (DWORD_PTR)__FILE__ ": TRASH_Creating"}
};
static CRITICAL_SECTION TRASH_Creating = { &TRASH_Creating_Debug, -1, 0, 0, 0, 0 };

static const char trashinfo_suffix[] = ".trashinfo";
static const char trashinfo_header[] = "[Trash Info]\n";
static const char trashinfo_group[] = "Trash Info";

typedef struct
{
    char *info_dir;
    char *files_dir;
    dev_t device;
} TRASH_BUCKET;

static TRASH_BUCKET *home_trash=NULL;

static char *init_home_dir(const char *subpath)
{
    char *path = XDG_BuildPath(XDG_DATA_HOME, subpath);
    if (path == NULL) return NULL;
    if (!XDG_MakeDirs(path))
    {
        ERR("Couldn't create directory %s (errno=%d). Trash won't be available\n", debugstr_a(path), errno);
        SHFree(path);
        path=NULL;
    }
    return path;
}

static TRASH_BUCKET *TRASH_CreateHomeBucket(void)
{
    TRASH_BUCKET *bucket;
    struct stat trash_stat;
    char *trash_path = NULL;
    
    bucket = SHAlloc(sizeof(TRASH_BUCKET));
    if (bucket == NULL)
    {
        errno = ENOMEM;
        goto error;
    }
    memset(bucket, 0, sizeof(*bucket));
    bucket->info_dir = init_home_dir("Trash/info/");
    if (bucket->info_dir == NULL) goto error;
    bucket->files_dir = init_home_dir("Trash/files/");
    if (bucket->files_dir == NULL) goto error;
    
    trash_path = XDG_BuildPath(XDG_DATA_HOME, "Trash/");
    if (stat(trash_path, &trash_stat) == -1)
        goto error;
    bucket->device = trash_stat.st_dev;
    SHFree(trash_path);
    return bucket;
error:
    SHFree(trash_path);
    if (bucket)
    {
        SHFree(bucket->info_dir);
        SHFree(bucket->files_dir);
    }
    SHFree(bucket);
    return NULL;
}

static BOOL TRASH_EnsureInitialized(void)
{
    if (home_trash == NULL)
    {
        EnterCriticalSection(&TRASH_Creating);
        if (home_trash == NULL)
            home_trash = TRASH_CreateHomeBucket();
        LeaveCriticalSection(&TRASH_Creating);
    }

    if (home_trash == NULL)
    {
        ERR("Couldn't initialize home trash (errno=%d)\n", errno);
        return FALSE;
    }
    return TRUE;
}

static BOOL file_good_for_bucket(const TRASH_BUCKET *pBucket, const struct stat *file_stat)
{
    if (pBucket->device != file_stat->st_dev)
        return FALSE;
    return TRUE;
}

BOOL TRASH_CanTrashFile(LPCWSTR wszPath)
{
    struct stat file_stat;
    char *unix_path;
    
    TRACE("(%s)\n", debugstr_w(wszPath));
    if (!TRASH_EnsureInitialized()) return FALSE;
    if (!(unix_path = wine_get_unix_file_name(wszPath)))
        return FALSE;
    if (lstat(unix_path, &file_stat)==-1)
    {
        HeapFree(GetProcessHeap(), 0, unix_path);
        return FALSE;
    }
    HeapFree(GetProcessHeap(), 0, unix_path);
    return file_good_for_bucket(home_trash, &file_stat);
}

/*
 * Try to create a single .trashinfo file. Return TRUE if successful, else FALSE
 */
static BOOL try_create_trashinfo_file(const char *info_dir, const char *file_name,
    const char *original_file_name)
{
    struct tm curr_time;
    time_t curr_time_secs;
    char datebuf[200];
    char *path = SHAlloc(strlen(info_dir)+strlen(file_name)+strlen(trashinfo_suffix)+1);
    int writer = -1;
    
    if (path==NULL) return FALSE;
    wsprintfA(path, "%s%s%s", info_dir, file_name, trashinfo_suffix);
    TRACE("Trying to create '%s'\n", path);
    writer = open(path, O_CREAT|O_WRONLY|O_TRUNC|O_EXCL, 0600);
    if (writer==-1) goto error;
    
    write(writer, trashinfo_header, strlen(trashinfo_header));
    if (!XDG_WriteDesktopStringEntry(writer, "Path", XDG_URLENCODE, original_file_name))
        goto error;
    
    time(&curr_time_secs);
    localtime_r(&curr_time_secs, &curr_time);
    wnsprintfA(datebuf, 200, "%04d-%02d-%02dT%02d:%02d:%02d",
        curr_time.tm_year+1900,
        curr_time.tm_mon+1,
        curr_time.tm_mday,
        curr_time.tm_hour,
        curr_time.tm_min,
        curr_time.tm_sec);
    if (!XDG_WriteDesktopStringEntry(writer, "DeletionDate", 0, datebuf))
        goto error;
    close(writer);
    SHFree(path);
    return TRUE;

error:
    if (writer != -1)
    {
        close(writer);
        unlink(path);
    }
    SHFree(path);
    return FALSE;
}

/*
 * Try to create a .trashinfo file. This function will make several attempts with
 * different filenames. It will return the filename that succeded or NULL if a file
 * couldn't be created.
 */
static char *create_trashinfo(const char *info_dir, const char *file_path)
{
    const char *base_name;
    char *filename_buffer;
    unsigned int seed = (unsigned int)time(NULL);
    int i;

    errno = ENOMEM;       /* out-of-memory is the only case when errno isn't set */
    base_name = strrchr(file_path, '/');
    if (base_name == NULL)
        base_name = file_path;
    else
        base_name++;

    filename_buffer = SHAlloc(strlen(base_name)+9+1);
    if (filename_buffer == NULL)
        return NULL;
    lstrcpyA(filename_buffer, base_name);
    if (try_create_trashinfo_file(info_dir, filename_buffer, file_path))
        return filename_buffer;
    for (i=0; i<30; i++)
    {
        sprintf(filename_buffer, "%s-%d", base_name, i+1);
        if (try_create_trashinfo_file(info_dir, filename_buffer, file_path))
            return filename_buffer;
    }
    
    for (i=0; i<1000; i++)
    {
        sprintf(filename_buffer, "%s-%08x", base_name, rand_r(&seed));
        if (try_create_trashinfo_file(info_dir, filename_buffer, file_path))
            return filename_buffer;
    }
    
    WARN("Couldn't create trashinfo after 1031 tries (errno=%d)\n", errno);
    SHFree(filename_buffer);
    return NULL;
}

static void remove_trashinfo_file(const char *info_dir, const char *base_name)
{
    char *filename_buffer;
    
    filename_buffer = SHAlloc(lstrlenA(info_dir)+lstrlenA(base_name)+lstrlenA(trashinfo_suffix)+1);
    if (filename_buffer == NULL) return;
    sprintf(filename_buffer, "%s%s%s", info_dir, base_name, trashinfo_suffix);
    unlink(filename_buffer);
    SHFree(filename_buffer);
}

static BOOL TRASH_MoveFileToBucket(TRASH_BUCKET *pBucket, const char *unix_path)
{
    struct stat file_stat;
    char *trash_file_name = NULL;
    char *trash_path = NULL;
    BOOL ret = TRUE;

    if (lstat(unix_path, &file_stat)==-1)
        return FALSE;
    if (!file_good_for_bucket(pBucket, &file_stat))
        return FALSE;
        
    trash_file_name = create_trashinfo(pBucket->info_dir, unix_path);
    if (trash_file_name == NULL)
        return FALSE;
        
    trash_path = SHAlloc(strlen(pBucket->files_dir)+strlen(trash_file_name)+1);
    if (trash_path == NULL) goto error;
    lstrcpyA(trash_path, pBucket->files_dir);
    lstrcatA(trash_path, trash_file_name);
    
    if (rename(unix_path, trash_path)==0)
    {
        TRACE("rename succeded\n");
        goto cleanup;
    }
    
    /* TODO: try to manually move the file */
    ERR("Couldn't move file\n");
error:
    ret = FALSE;
    remove_trashinfo_file(pBucket->info_dir, trash_file_name);
cleanup:
    SHFree(trash_file_name);
    SHFree(trash_path);
    return ret;
}

BOOL TRASH_TrashFile(LPCWSTR wszPath)
{
    char *unix_path;
    BOOL result;
    
    TRACE("(%s)\n", debugstr_w(wszPath));
    if (!TRASH_EnsureInitialized()) return FALSE;
    if (!(unix_path = wine_get_unix_file_name(wszPath)))
        return FALSE;
    result = TRASH_MoveFileToBucket(home_trash, unix_path);
    HeapFree(GetProcessHeap(), 0, unix_path);
    return result;
}

/*
 * The item ID of a trashed element is built as follows:
 *  NUL byte                    - in most PIDLs the first byte is the type so we keep it constant
 *  WIN32_FIND_DATAW structure  - with data about original file attributes
 *  bucket name                 - currently only an empty string meaning the home bucket is supported
 *  trash file name             - a NUL-terminated string
 */
struct tagTRASH_ELEMENT
{
    TRASH_BUCKET *bucket;
    LPSTR filename;
};

static HRESULT TRASH_CreateSimplePIDL(const TRASH_ELEMENT *element, const WIN32_FIND_DATAW *data, LPITEMIDLIST *pidlOut)
{
    LPITEMIDLIST pidl = SHAlloc(2+1+sizeof(WIN32_FIND_DATAW)+1+lstrlenA(element->filename)+1+2);
    *pidlOut = NULL;
    if (pidl == NULL)
        return E_OUTOFMEMORY;
    pidl->mkid.cb = (USHORT)(2+1+sizeof(WIN32_FIND_DATAW)+1+lstrlenA(element->filename)+1);
    pidl->mkid.abID[0] = 0;
    memcpy(pidl->mkid.abID+1, data, sizeof(WIN32_FIND_DATAW));
    pidl->mkid.abID[1+sizeof(WIN32_FIND_DATAW)] = 0;
    lstrcpyA((LPSTR)(pidl->mkid.abID+1+sizeof(WIN32_FIND_DATAW)+1), element->filename);
    *(USHORT *)(pidl->mkid.abID+1+sizeof(WIN32_FIND_DATAW)+1+lstrlenA(element->filename)+1) = 0;
    *pidlOut = pidl;
    return S_OK;
}

/***********************************************************************
 *      TRASH_UnpackItemID [Internal]
 *
 * DESCRIPTION:
 * Extract the information stored in an Item ID. The TRASH_ELEMENT
 * identifies the element in the Trash. The WIN32_FIND_DATA contains the
 * information about the original file. The data->ftLastAccessTime contains
 * the deletion time
 *
 * PARAMETER(S):
 * [I] id : the ID of the item
 * [O] element : the trash element this item id contains. Can be NULL if not needed
 * [O] data : the WIN32_FIND_DATA of the original file. Can be NULL is not needed
 */                 
HRESULT TRASH_UnpackItemID(LPCSHITEMID id, TRASH_ELEMENT *element, WIN32_FIND_DATAW *data)
{
    if (id->cb < 2+1+sizeof(WIN32_FIND_DATAW)+2)
        return E_INVALIDARG;
    if (id->abID[0] != 0 || id->abID[1+sizeof(WIN32_FIND_DATAW)] != 0)
        return E_INVALIDARG;
    if (memchr(id->abID+1+sizeof(WIN32_FIND_DATAW)+1, 0, id->cb-(2+1+sizeof(WIN32_FIND_DATAW)+1)) == NULL)
        return E_INVALIDARG;

    if (data != NULL)
        *data = *(WIN32_FIND_DATAW *)(id->abID+1);
    if (element != NULL)
    {
        element->bucket = home_trash;
        element->filename = StrDupA((LPCSTR)(id->abID+1+sizeof(WIN32_FIND_DATAW)+1));
        if (element->filename == NULL)
            return E_OUTOFMEMORY;
    }
    return S_OK;
}

void TRASH_DisposeElement(TRASH_ELEMENT *element)
{
    SHFree(element->filename);
}

static HRESULT TRASH_GetDetails(const TRASH_ELEMENT *element, WIN32_FIND_DATAW *data)
{
    LPSTR path = NULL;
    XDG_PARSED_FILE *parsed = NULL;
    char *original_file_name = NULL;
    char *deletion_date = NULL;
    int fd = -1;
    struct stat stats;
    HRESULT ret = S_FALSE;
    LPWSTR original_dos_name;
    int suffix_length = lstrlenA(trashinfo_suffix);
    int filename_length = lstrlenA(element->filename);
    int files_length = lstrlenA(element->bucket->files_dir);
    int path_length = max(lstrlenA(element->bucket->info_dir), files_length);
    
    path = SHAlloc(path_length + filename_length + 1);
    if (path == NULL) return E_OUTOFMEMORY;
    wsprintfA(path, "%s%s", element->bucket->files_dir, element->filename);
    path[path_length + filename_length - suffix_length] = 0;  /* remove the '.trashinfo' */    
    if (lstat(path, &stats) == -1)
    {
        ERR("Error accessing data file for trashinfo %s (errno=%d)\n", element->filename, errno);
        goto failed;
    }
    
    wsprintfA(path, "%s%s", element->bucket->info_dir, element->filename);
    fd = open(path, O_RDONLY);
    if (fd == -1)
    {
        ERR("Couldn't open trashinfo file %s (errno=%d)\n", path, errno);
        goto failed;
    }
    
    parsed = XDG_ParseDesktopFile(fd);
    if (parsed == NULL)
    {
        ERR("Parse error in trashinfo file %s\n", path);
        goto failed;
    }
    
    original_file_name = XDG_GetStringValue(parsed, trashinfo_group, "Path", XDG_URLENCODE);
    if (original_file_name == NULL)
    {
        ERR("No 'Path' entry in trashinfo file\n");
        goto failed;
    }
    
    ZeroMemory(data, sizeof(*data));
    data->nFileSizeHigh = (DWORD)((LONGLONG)stats.st_size>>32);
    data->nFileSizeLow = stats.st_size & 0xffffffff;
    RtlSecondsSince1970ToTime(stats.st_mtime, (LARGE_INTEGER *)&data->ftLastWriteTime);
    
    original_dos_name = wine_get_dos_file_name(original_file_name);
    if (original_dos_name != NULL)
    {
        lstrcpynW(data->cFileName, original_dos_name, MAX_PATH);
        SHFree(original_dos_name);
    }
    else
    {
        /* show only the file name */
        char *filename = strrchr(original_file_name, '/');
        if (filename == NULL)
            filename = original_file_name;
        MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, data->cFileName, MAX_PATH);
    }
    
    deletion_date = XDG_GetStringValue(parsed, trashinfo_group, "DeletionDate", 0);
    if (deletion_date)
    {
        struct tm del_time;
        time_t del_secs;
        
        sscanf(deletion_date, "%d-%d-%dT%d:%d:%d",
            &del_time.tm_year, &del_time.tm_mon, &del_time.tm_mday,
            &del_time.tm_hour, &del_time.tm_min, &del_time.tm_sec);
        del_time.tm_year -= 1900;
        del_time.tm_mon--;
        del_secs = mktime(&del_time);
        
        RtlSecondsSince1970ToTime(del_secs, (LARGE_INTEGER *)&data->ftLastAccessTime);
    }
    
    ret = S_OK;
failed:
    SHFree(path);
    SHFree(original_file_name);
    SHFree(deletion_date);
    if (fd != -1)
        close(fd);
    XDG_FreeParsedFile(parsed);
    return ret;
}

static INT CALLBACK free_item_callback(void *item, void *lParam)
{
    SHFree(item);
    return TRUE;
}

static HDPA enum_bucket_trashinfos(const TRASH_BUCKET *bucket, int *count)
{
    HDPA ret = DPA_Create(32);
    struct dirent *entry;
    DIR *dir = NULL;
    
    errno = ENOMEM;
    *count = 0;
    if (ret == NULL) goto failed;
    dir = opendir(bucket->info_dir);
    if (dir == NULL) goto failed;
    while ((entry = readdir(dir)) != NULL)
    {
        LPSTR filename;
        int namelen = lstrlenA(entry->d_name);
        int suffixlen = lstrlenA(trashinfo_suffix);
        if (namelen <= suffixlen ||
                lstrcmpA(entry->d_name+namelen-suffixlen, trashinfo_suffix) != 0)
            continue;

        filename = StrDupA(entry->d_name);
        if (filename == NULL)
            goto failed;
        if (DPA_InsertPtr(ret, DPA_APPEND, filename) == -1)
        {
            SHFree(filename);
            goto failed;
        }
        (*count)++;
    }
    closedir(dir);
    return ret;
failed:
    if (dir) closedir(dir);
    if (ret)
        DPA_DestroyCallback(ret, free_item_callback, NULL);
    return NULL;
}

HRESULT TRASH_EnumItems(LPITEMIDLIST **pidls, int *count)
{
    int ti_count;
    int pos=0, i;
    HRESULT err = E_OUTOFMEMORY;
    HDPA tinfs;
    
    if (!TRASH_EnsureInitialized()) return E_FAIL;
    tinfs = enum_bucket_trashinfos(home_trash, &ti_count);
    if (tinfs == NULL) return E_FAIL;
    *pidls = SHAlloc(sizeof(LPITEMIDLIST)*ti_count);
    if (!*pidls) goto failed;
    for (i=0; i<ti_count; i++)
    {
        WIN32_FIND_DATAW data;
        TRASH_ELEMENT elem;
        
        elem.bucket = home_trash;
        elem.filename = DPA_GetPtr(tinfs, i);
        if (FAILED(err = TRASH_GetDetails(&elem, &data)))
            goto failed;
        if (err == S_FALSE)
            continue;
        if (FAILED(err = TRASH_CreateSimplePIDL(&elem, &data, &(*pidls)[pos])))
            goto failed;
        pos++;
    }
    *count = pos;
    DPA_DestroyCallback(tinfs, free_item_callback, NULL);
    return S_OK;
failed:
    if (*pidls != NULL)
    {
        int j;
        for (j=0; j<pos; j++)
            SHFree((*pidls)[j]);
        SHFree(*pidls);
    }
    DPA_DestroyCallback(tinfs, free_item_callback, NULL);
    
    return err;
}
