#!/usr/bin/env python
# Copyright (c) 2011-2012 Chanrithy Thim
#
# AUTHOR:
# Chanrithy Thim <12rithy@gmail.com>
#
# This file is part of Appshell
#
# Appshell 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 2 of the License, or (at
# your option) any later version.
#
# Appshell 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 AptUrl; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

import sys
import os
import os.path

from manifest import *
from utils import *

fexec = ("#!/bin/bash\n"
        "EXEC=\"@@EXEC@@\"\n"
        "cd \"$(dirname \"${0}\")\"\n"
        "LD_LIBRARY_PATH=\"./lib:${LD_LIBRARY_PATH}\" "
        "PATH=\"./bin/:./sbin/:./games/:../bin/:../sbin/:${PATH}\" "
        "exec \"$EXEC\" \"$@\"")
        
def build():
    if not os.path.exists(os.path.realpath(os.curdir) + "/manifest.xml"):
        print "Cannot find manifest file"
    else:
        if os.path.exists("output"):
            print "Cleaning old files..."
            os.system("rm -rf output")
        os.makedirs("output")
        
        # Parse manifest
        manifest = Manifest("manifest.xml")
        
        # Copy files
        print "Copying root files..."
        ret, out, err = run_cmd("cp -r root output/")
        if ret != 0:
            print "ERROR: %s" % err.strip()
            sys.exit(1)
        if os.path.exists("extractout"):
            print "Copying extractout files..."
            ret, out, err = run_cmd("cp -r extractout output/")
            if ret != 0:
                print "ERROR: %s" % err.strip()
                sys.exit(1)
        print "Copying resources files..."
        ret, out, err = run_cmd("cp -r res output/")
        if ret != 0:
            print "ERROR: %s" % err.strip()
            sys.exit(1)
        ret, out, err = run_cmd("cp -r manifest.xml output/")
        if ret != 0:
            print "ERROR: %s" % err.strip()
            sys.exit(1)
        
        # Create start and other exec 
        start = file("output/root/start", 'w')
        start.write(fexec.replace("@@EXEC@@", manifest.exec_main))
        start.close()
        os.chmod("output/root/start", 0755)
        
        for _exec in manifest.execs:
            path = "output/root/%s" % _exec
            f = file(path, 'w')
            f.write(fexec.replace("@@EXEC@@", _exec))
            f.close()
            os.chmod(path, 0755)
        
        # Check and create extract out list
        if os.path.exists("extractout"):
            f = file("output/extractout.list", 'w')
            for root, dirs, files in os.walk("extractout"):
                for name in files:
                    path = os.path.join(root, name)
                    f.write("%s\n" % remove_prefix("extractout", path))
                
                for name in dirs:
                    path = os.path.join(root, name)
                    if os.path.islink(path):
                        f.write("%s\n" % remove_prefix("extractout", path))
                
                if len(files) == 0 and len(dirs) == 0:
                    f.write("%s\n" % remove_prefix("extractout", root))
            f.close()
        
        # Create iso
        print "Creating app image"
        cmd = ("xorriso -volid \"Appshell Application\" -dev \"output/%s %s-%s.app\" "
        "-padding 0 -map output/ / -- -zisofs level=9:block_size=128k -chown_r 0 / -- set_filter_r --zisofs /") % (manifest.name, 
        manifest.version, manifest.release)
        ret, out, err = run_cmd(cmd) 
        if ret != 0:
            print "ERROR: %s" % err.strip()
            sys.exit(1)
        
        # Make output file execuable 
        print "Finishing..."
        path = "output/%s %s-%s.app" % (manifest.name, manifest.version, manifest.release)
        offset = os.stat(path)[6]+1
        f = file(os.path.realpath(path), 'r+')
        f.truncate(offset-1)
        f.write('#!/usr/bin/env appshell-runtime')
        f.close()
        os.chmod(path, 0755)
        print "Finished: %s" % path
        
def is_appimage(fpath):
    if os.path.exists(fpath):
        if not os.path.isdir(fpath):
            cmd = "head -n 1 \"%s\" | cut -c 1-31" % fpath
            ret, out, err = run_cmd(cmd)
            if ret != 0:
                print "ERROR: %s" % err.strip()
                sys.exit(1)
            if out.strip() != "#!/usr/bin/env appshell-runtime":
                return False
            else:
                return True
    return False

def mount(fpath, mpath):
    cmd = "mount -t auto -o loop \"%s\" \"%s\"" % (fpath, mpath)
    ret, out, err = run_cmd(cmd)
    if ret != 0:
        print "ERROR: %s" % err.strip()
        sys.exit(1)

def umount(mpath):
    cmd = "umount \"%s\"" % mpath
    ret, out, err = run_cmd(cmd)
    if ret != 0:
        print "ERROR: %s" % err.strip()
        sys.exit(1)

def check_installed(appname):
    path = "/var/lib/appshell/%s/manifest.xml" % appname
    if os.path.exists(path):
        return True
    else:
        return False

def get_installed_version(appname):
    path = "/var/lib/appshell/%s/manifest.xml" % appname
    manifest = Manifest(path)
    return manifest.version

def install(appname, fpath, mpath):
    print "Copying app file to system"
    cmd = "cp -rf \"%s\" \"/Apps/%s.app\"" % (fpath, appname)
    ret, out, err = run_cmd(cmd)
    if ret != 0:
        print "COPY ERROR: %s" % err.strip()
        sys.exit(1)
    
    extout = "%s/extractout" % mpath
    if os.path.exists(extout):
        print "Extracting extra files to system"
        cmd = "cp -rf \"%s/*\" /" % (extout)
        ret, out, err = run_cmd(cmd)
        if ret != 0:
            print "COPY ERROR: %s" % err.strip()
            sys.exit(1)
    
    print "Setting up %s" % appname
    intdir = "/var/lib/appshell/%s" % appname
    os.mkdirs(intdir)
    
    resdir = "%s/res" % mpath
    f = file(intdir + "/desktop.list", 'w')
    for n in os.listdir(resdir + "/desktop"):
        cmd = "cp -rf \"%s\" /usr/share/applications/" % n
        ret, out, err = run_cmd(cmd)
        if ret != 0:
            print "COPY ERROR: %s" % err.strip()
            sys.exit(1)
        f.write("%s\n" % n)
    f.close()
    f = file(intdir + "/icons.list", 'w')
    for n in os.listdir(resdir + "/icons"):
        cmd = "cp -rf \"%s\" /usr/share/icons/" % n
        ret, out, err = run_cmd(cmd)
        if ret != 0:
            print "COPY ERROR: %s" % err.strip()
            sys.exit(1)
        f.write("%s\n" % n)
    f.close()
    f = file(intdir + "/mime.list", 'w')
    for n in os.listdir(resdir + "/mime"):
        cmd = "cp -rf \"%s\" /usr/share/mime/" % n
        ret, out, err = run_cmd(cmd)
        if ret != 0:
            print "COPY ERROR: %s" % err.strip()
            sys.exit(1)
        f.write("%s\n" % n)
    f.close()
    if os.path.exists(resdir + "/scripts/install.sh"):
        print "Running post install script..."
        cmd = "\"%s/scripts/install.sh\"" % resdir
        ret, out, err = run_cmd(cmd)
        if ret != 0:
            print "RUN ERROR: %s" % err.strip()
            sys.exit(1)
    
    cmd = "cp -f \"%s/manifest.xml\" %s/" % (mpath, intdir)
    ret, out, err = run_cmd(cmd)
    if ret != 0:
        print "COPY ERROR: %s" % err.strip()
        sys.exit(1)
    
    if os.path.exists(resdir + "/scripts/uninstall.sh"):
        cmd = "cp -f \"%s/scripts/uninstall.sh\" %s/" % (resdir, intdir)
        ret, out, err = run_cmd(cmd)
        if ret != 0:
            print "COPY ERROR: %s" % err.strip()
            sys.exit(1)
    if os.path.exists(mpath + "/extractout.list"):
        cmd = "cp -f \"%s/extractout.list\" %s/" % (mpath, intdir)
        ret, out, err = run_cmd(cmd)
        if ret != 0:
            print "COPY ERROR: %s" % err.strip()
            sys.exit(1)
   
def uninstall(appname, fpath):
    print "Deleting appimage..."
    cmd = "rm -rf \"%s\"" % (fpath)
    ret, out, err = run_cmd(cmd)
    if ret != 0:
        print "DELETE ERROR: %s" % err.strip()
        sys.exit(1)
    
    print ("Removing extra files...")
    intdir = "/var/lib/appshell/%s" % appname
    if os.path.exists(intdir + "/desktop.list"):
        f = file(extlist, 'r\n')
        for i in f.readlines():
            if not utils.remove_with_path(i.rstrip()):
                sys.exit(1)
                
    if os.path.exists(intdir + "/icons.list"):
        f = file(extlist, 'r\n')
        for i in f.readlines():
            if not utils.remove_with_path(i.rstrip()):
                sys.exit(1)
                
    if os.path.exists(intdir + "/mime.list"):
        f = file(extlist, 'r\n')
        for i in f.readlines():
            if not utils.remove_with_path(i.rstrip()):
                sys.exit(1)
                
    if os.path.exists(intdir + "/extractout.list"):
        print ("Removing extra files...")
        f = file(extlist, 'r\n')
        for i in f.readlines():
            if not utils.remove_with_path(i.rstrip()):
                sys.exit(1)
    
    if os.path.exists(intdir + "/uninstall.sh"):
        print "Running post uninstall script..."
        cmd = "\"%s/uninstall.sh\"" % intdir
        ret, out, err = run_cmd(cmd)
        if ret != 0:
            print "RUN ERROR: %s" % err.strip()
            sys.exit(1)
            
    print "Cleaning..."
    cmd = "rm -rf \"/var/lib/appshell/%s\"" % (appname)
    ret, out, err = run_cmd(cmd)
    if ret != 0:
        print "DELETE ERROR: %s" % err.strip()
        sys.exit(1)
    print "Finished"
                
