/*
 * 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
#include <dirent.h>

#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]
 *
 * DESCRITION:
 * 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;
}
