# __init__.py
# 
# Copyright (C) 2005-2007 Mykola Lynnyk <pydefiner@gmail.com>
# Copyright (C) 2008-2009 Stefan J. Betz <stefan_betz@gmx.net>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import gettext
import ConfigParser
from ConfigParser import SafeConfigParser
from os import environ, F_OK, R_OK, W_OK, X_OK, access, mkdir, chmod, stat
from os.path import isdir
from stat import S_IRUSR, S_IWUSR, S_ISUID, ST_MODE
from sqlite3 import connect, register_adapter, version_info
from StringIO import StringIO
from threading import RLock
from pyneighborhood.misc import homeconfdir, parse_args, get_desktop_environ, push_notification
from pyneighborhood.database import init_database

_ = gettext.gettext

# Default configuration
DEFAULT_CONFIG = """
[Main]
cleanup_dirs = True
enable_file_manager = True
enable_sudo = True
filemanager = /usr/bin/nautilus
loglevel = 0
mount_directory =
password = 
sudo = /usr/bin/pkexec --disable-internal-agent
username = 
hidden_shares = False
[CIFS]
mount = /sbin/mount.cifs
unmount = /sbin/umount.cifs
options =
"""

# DO NOT move this !!!
# Parsing arguments
parse_args()

# Memory database of SQLite 3
db = connect(":memory:", check_same_thread = False)
dblock = RLock()
# Initialise the database
init_database(db)
# Fixing SQLite 2.4.1 behavior first occured in Python 2.6:
if version_info >= (2,4,1):
    register_adapter(str, lambda s:s.decode('utf-8'))

config = SafeConfigParser()
config.readfp(StringIO(DEFAULT_CONFIG))

if not isdir(homeconfdir()):
    push_notification(_("Creating config directory...\n"), level=1)
    mkdir(homeconfdir())

if not access(homeconfdir() + "/config", F_OK):
    push_notification(_("Creating Default Config...\n"), level=1)
    config.set("Main", "mount_directory", environ["HOME"] + "/pyNeighborhood")
    f = file(homeconfdir() + "/config", "w")
    config.write(f)
    f.flush()
    f.close()
    del f
    chmod(homeconfdir() + "/config", S_IRUSR + S_IWUSR)
else:
    config.read(homeconfdir() + "/config")

if not isdir(config.get("Main", "mount_directory")):
    try:
        push_notification(_("Creating mount base directory %s\n") % config.get("Main", "mount_directory"), level=1)
        mkdir(config.get("Main", "mount_directory"))
    except:
        push_notification(_("Error creating mount base directory\n"), level=2)
elif not access(config.get("Main", "mount_directory"), R_OK | W_OK | X_OK):
    push_notification(_("Lacking permission to access mount base directory %s\n") % config.get("Main", "mount_directory"), level=2)

# Ensure that executables like nautilus, ... really exist
# The conditions are valid defaults defined below...
defaults =  {"filemanager": "/usr/bin/nautilus"}

for file in defaults.keys():
    if not access( config.get("Main", file), F_OK | X_OK ):
        push_notification( _("%(file)s isn't accessable, falling back to default: %(default)s\n")
                    % { "file": config.get("Main", file),
                        "default": defaults[file] }, level=2 )
        config.set("Main", file, defaults[file])

for utility in ["mount", "unmount"]:
    if not access( config.get("CIFS", utility), F_OK ):
        config.set('CIFS',utility,'/sbin/%s.cifs' % ('mount' if utility == 'mount' else 'umount'))
    if not access( config.get("CIFS", utility), F_OK):
        config.set('CIFS',utility,'/bin/%s' % ('mount' if utility == 'mount' else 'umount'))
        push_notification(_("Using %(util)s for future operations.\n") % { "util": config.get('CIFS',utility) }, level=1)
        
if not access( config.get("Main", "sudo"), F_OK | X_OK):
    push_notification(_("%(sudo)s isn't accessable... trying to determine correct sudo wrapper...\n") % { "sudo": config.get("Main", "sudo") }, level=2)
    config.set("Main", "sudo", "/usr/bin/pkexec --disable-internal-agent")

fileman_defaults = { "gnome":   "/usr/bin/nautilus",
                     "kde":     "/usr/bin/dolphin",
                     "lxde":    "/usr/bin/pcmanfm",
                     "xfce":    "/usr/bin/thunar",
                     "default": "/usr/bin/nautilus" }
        
if not access( config.get("Main", "filemanager"), F_OK | X_OK):
    push_notification(_("%(fileman)s isn't accessable... trying to determine correct filemanager...\n") % { "fileman": config.get("Main", "filemanager") }, level=2)
    if get_desktop_environ() in fileman_defaults.keys():
        push_notification(_("Detected %(de)s desktop environment... falling back to %(fileman)s as filemanager...\n") % { "de": get_desktop_environ(), "fileman": fileman_defaults[get_desktop_environ()] } )
        config.set("Main", "filemanager", fileman_defaults[get_desktop_environ()])
    else:
        push_notification(_("Couldn't get valid filemanager for detected desktop environment %(de)s, falling back to default %(default)s...\n") % { "de": get_desktop_environ(), "default": fileman_defaults["default"] }, level=2)
        config.set("Main", "filemanager", fileman_defaults["default"])
     

# Checking for SUID bit
# If it's not set, we'll force sudo
if ( stat( config.get('CIFS','mount') )[ST_MODE] & S_ISUID ) == 0:
    if not config.get("Main", "enable_sudo") == "True":
        config.set("Main", "enable_sudo", "True")
        push_notification( _("SUID bit on %(file)s is not set, forcing sudo usage...\n") % { "file": config.get('CIFS', 'mount') } ,level=1)
