/*
   Copyright (C) 2008 Norbert Frese <nf2 at scheinwelt at>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License (LGPL) as published by the Free Software Foundation;
   either version 2 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#include "giobridge-errormapper.h"

#include <kurl.h>
#include <kdebug.h>
#include <kio/ioslave_defaults.h>
#include <kio/global.h>
#include <glib.h>
#include <gio/gio.h>


using namespace KIO;

GioBridgeErrorMapper::GioBridgeErrorMapper(GError * err, OperationHint opHint, const KUrl & url, const KUrl & targetUrl)
{
    
    kDebug() << "GError code=" << err->code << " message=" << err->message << endl;
    
    QString gErrMessage(err->message);
    QString gErrMessageWBrackets = QString(" (") + gErrMessage + ")";  
    QString bothUrls = targetUrl.isEmpty() ? url.url() : url.url() + " | " + targetUrl.url(); 
    QString bothFileNames = targetUrl.isEmpty() ? url.fileName() : url.fileName () + " | " + targetUrl.fileName();
    
    int kioGenericCode = ERR_UNSUPPORTED_ACTION;
    QString kioGenericText = gErrMessage;
    
    // create a the KIO error id for generic or untranslatable errors
    
    switch (opHint)
    {
        case OP_READ   : kioGenericCode = ERR_COULD_NOT_READ;
                         kioGenericText =  url.url() + gErrMessageWBrackets;
                         break;
                         
        case OP_WRITE  : kioGenericCode = ERR_COULD_NOT_WRITE;
                         kioGenericText =  url.url() + gErrMessageWBrackets;
                         break;
                         
        case OP_CLOSE  : // dont know
                         break;
                         
                         
        case OP_STAT   : kioGenericCode = ERR_COULD_NOT_STAT;
                         kioGenericText =  url.url() + gErrMessageWBrackets;
                         break;
            
        case OP_LIST   : // dont know
                         break;
                         
        case OP_MKDIR  : kioGenericCode = ERR_COULD_NOT_MKDIR;
                         kioGenericText =  url.url() + gErrMessageWBrackets;
                         break;
                         
        case OP_RMDIR  : kioGenericCode = ERR_COULD_NOT_RMDIR;
                         kioGenericText =  url.url() + gErrMessageWBrackets;
                         break;
                         
        case OP_RENAME : kioGenericCode = ERR_CANNOT_RENAME;
                         kioGenericText =  url.url() + gErrMessageWBrackets;
                         break;
                         
        case OP_CHMOD  : kioGenericCode = ERR_CANNOT_CHMOD;
                         kioGenericText =  url.url() + gErrMessageWBrackets;
                         break;
                         
        case OP_CHOWN  : kioGenericCode = ERR_CANNOT_CHOWN;
                         kioGenericText =  url.url() + gErrMessageWBrackets;
                         break;
                         
        case OP_DELETE : kioGenericCode = ERR_CANNOT_DELETE;
                         kioGenericText =  url.url() + gErrMessageWBrackets;
                         break;
                         
        case OP_SETTIME: kioGenericCode = ERR_CANNOT_SETTIME;
                         kioGenericText =  url.url() + gErrMessageWBrackets;
                         break;
                         
        default        : break;
    }
    
    // try to translate the error code
    
    int gioErrorCode= err->code;
    switch (gioErrorCode)
    {
        case G_IO_ERROR_FAILED              : resultText = kioGenericText;
                                              resultErrId = kioGenericCode;
                                              break;
                                              
        case G_IO_ERROR_NOT_FOUND           : resultText = url.url() + gErrMessageWBrackets;
                                              resultErrId = ERR_DOES_NOT_EXIST;
                                              break;
        
        case G_IO_ERROR_EXISTS              : resultText = url.url() + gErrMessageWBrackets;
                                              resultErrId = opHint & IS_FILE_OP ? ERR_FILE_ALREADY_EXIST : ERR_DIR_ALREADY_EXIST;
                                              break;
        
        case G_IO_ERROR_IS_DIRECTORY        : resultText = url.url() + gErrMessageWBrackets;
                                              resultErrId = ERR_IS_DIRECTORY;
                                              break;
            
        case G_IO_ERROR_NOT_DIRECTORY       : resultText = url.url() + gErrMessageWBrackets;
                                              resultErrId = opHint & IS_FILE_OP ? ERR_UNSUPPORTED_ACTION : ERR_IS_FILE;
                                              break;
        
        case G_IO_ERROR_NOT_EMPTY           : resultText = url.url() + gErrMessageWBrackets;
                                              resultErrId = ERR_COULD_NOT_RMDIR;
                                              break;
        
        case G_IO_ERROR_NOT_REGULAR_FILE    : resultText = url.url() + gErrMessageWBrackets;
                                              resultErrId = opHint & IS_FILE_OP ? ERR_IS_DIRECTORY : ERR_UNSUPPORTED_ACTION;
                                              break;
                                              
        case G_IO_ERROR_NOT_SYMBOLIC_LINK   : resultText =  kioGenericText;
                                              resultErrId = kioGenericCode;  // TODO: when does this occur?
                                              break;
        
        case G_IO_ERROR_NOT_MOUNTABLE_FILE  : resultText = url.url() + gErrMessageWBrackets;
                                              resultErrId = ERR_COULD_NOT_MOUNT;
                                              break;
        
        case G_IO_ERROR_FILENAME_TOO_LONG   : resultText = bothUrls + gErrMessageWBrackets;
                                              resultErrId = ERR_MALFORMED_URL;
                                              break;
        
        case G_IO_ERROR_INVALID_FILENAME    : resultText = bothUrls + gErrMessageWBrackets;
                                              resultErrId = ERR_MALFORMED_URL;
                                              break;
        
        case G_IO_ERROR_TOO_MANY_LINKS      : resultText = url.url() + gErrMessageWBrackets;
                                              resultErrId = ERR_CYCLIC_LINK;
                                              break;
        
        case G_IO_ERROR_NO_SPACE            : resultText = url.url() + gErrMessageWBrackets;
                                              resultErrId = ERR_DISK_FULL;
                                              break;
        
        case G_IO_ERROR_INVALID_ARGUMENT    : resultText = kioGenericText;
                                              resultErrId = kioGenericCode;
                                              break;
        
        case G_IO_ERROR_PERMISSION_DENIED   : resultText = url.url() + gErrMessageWBrackets;
                                              resultErrId = ERR_ACCESS_DENIED;
                                              break;
        
        case G_IO_ERROR_NOT_SUPPORTED       : resultText = kioGenericText;
                                              resultErrId = kioGenericCode;
                                              break;
        
        case G_IO_ERROR_NOT_MOUNTED         : resultText = url.url() + gErrMessageWBrackets;
                                              resultErrId = ERR_ACCESS_DENIED;
                                              break;
        
        case G_IO_ERROR_ALREADY_MOUNTED     : resultText = url.url() + gErrMessageWBrackets;
                                              resultErrId = ERR_COULD_NOT_MOUNT; 
                                              break;
        
        case G_IO_ERROR_CLOSED              : resultText = kioGenericText;
                                              resultErrId = kioGenericCode; // TODO: add KIO error code?
                                              break;
        
        case G_IO_ERROR_CANCELLED           : resultText = gErrMessage;
                                              resultErrId = ERR_USER_CANCELED;
                                              break;
        
        case G_IO_ERROR_PENDING             : resultText = kioGenericText;
                                              resultErrId = kioGenericCode; // TODO: add KIO error code?
                                              break;
        
        case G_IO_ERROR_READ_ONLY           : resultText = url.url() + gErrMessageWBrackets;
                                              resultErrId = ERR_WRITE_ACCESS_DENIED; // TODO: needs a better translation
                                              break;
        
        case G_IO_ERROR_CANT_CREATE_BACKUP  : resultText = kioGenericText;
                                              resultErrId = kioGenericCode; // won't happen, because we don't use GIO beckups?
                                              break;
        
        case G_IO_ERROR_WRONG_ETAG          : resultText = kioGenericText;
                                              resultErrId = kioGenericCode; // won't happen?
                                              break;
        
        case G_IO_ERROR_TIMED_OUT           : resultText = url.host() + gErrMessageWBrackets;
                                              resultErrId = ERR_SERVER_TIMEOUT; 
                                              break;
        
        case G_IO_ERROR_WOULD_RECURSE       : resultText = kioGenericText;
                                              resultErrId = kioGenericCode; // don't know when this happens
                                              break;
        
        case G_IO_ERROR_BUSY                : resultText = kioGenericText; // TODO: New KDE error Code?
                                              resultErrId = kioGenericCode;
                                              break;
        
        case G_IO_ERROR_WOULD_BLOCK         : resultText = kioGenericText; // won't happen?
                                              resultErrId = kioGenericCode;
                                              break;
        
        case G_IO_ERROR_HOST_NOT_FOUND      : resultText = url.url() + gErrMessageWBrackets;
                                              resultErrId = ERR_SERVICE_NOT_AVAILABLE;
                                              break;
        
        case G_IO_ERROR_WOULD_MERGE         : resultText = kioGenericText;
                                              resultErrId = kioGenericCode; // what's this?
                                              break;
        
        case G_IO_ERROR_FAILED_HANDLED      : resultText = kioGenericText;
                                              resultErrId = kioGenericCode; // internal, won't occur?
                                              break;
        
        default                             : resultText = kioGenericText + "; Unknown GIO Error code " + QString().setNum(gioErrorCode);
                                              resultErrId = kioGenericCode; 
                                              break;

    }
}
