#!/usr/bin/python3
# encoding: utf-8
#
# 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/>.
#

from __future__ import absolute_import, print_function, unicode_literals

import os
import sys
import gettext
import argparse
try:
    from urllib.parse import unquote
except:
    from urllib import unquote

from efl import elementary

from epack.backend import load_backend
from epack.gui import MainWin



# install the _() and ngettext() functions in the main namespace
install_prefix = os.path.dirname(os.path.dirname(__file__))
locale_dir = os.path.join(install_prefix, 'share', 'locale')
gettext.install('epack', names='ngettext', localedir=locale_dir)



class EpackApplication(object):
    def __init__(self, args):
        self.file_name = None    # full path of the loaded archive
        self.dest_folder = None  # destination folder for extract operation
        self.backend = None      # the backend currently in use
        self.delete_after_extract = False
        self.args = args

        self.main_win = MainWin(self)

        if args.archive:
            self.load_file(args.archive)
        if args.destination:
            self.dest_folder = args.destination

    def load_file(self, fname):
        # cleanup and check file name
        if fname.startswith('file://'):
            fname = unquote(fname)[7:]
        else:
            fname = os.path.abspath(fname)

        if not os.path.isfile(fname):
            self.main_win.show_error_msg(_('Cannot read file:<br>%s') % fname)
            return

        # search a backend cabable of reading this file
        self.backend = load_backend(fname)
        if self.backend is None:
            self.main_win.show_error_msg(_('Cannot read archive'))
            return

        # start the archive listing -> line:157
        self.file_name = fname
        self.dest_folder = os.path.dirname(fname)
        self.backend.list_content(fname, self._list_done_cb)
        self.main_win.update_ui(listing_in_progress=True)

        # ...and print some info
        print('Reading file: "%s"' % fname)
        print('Destination folder: "%s"' % self.dest_folder)
        print('Using backend: "%s"' % self.backend.name)

    def _list_done_cb(self, file_list):
        self.main_win.tree_populate(file_list)
        self.main_win.update_ui()
        if self.args.extract is True:
            self.extract_archive()

    def extract_archive(self):
        if not os.path.exists(self.dest_folder):
            os.mkdir(self.dest_folder)

        self.backend.extract(self.file_name, self.dest_folder,
                             self._extract_progress_cb,
                             self._extract_done_cb)

    def _extract_progress_cb(self, progress, fname):
        self.main_win.extract_progress(progress, fname)

    def _extract_done_cb(self, result):
        self.main_win.extract_finished()
        if result == 'success':
            if self.delete_after_extract:
                os.remove(self.file_name)
            if self.args.quit is True:
                self.exit()
            else:
                self.main_win.ask_what_to_do_next()
        elif result == 'stopped':
            pass
        else:
            self.main_win.show_error_msg(result)

    def abort_operation(self):
        self.backend.abort()

    def exit(self):
        if self.backend:
            self.backend.abort()
        elementary.exit()

if __name__ == "__main__":

    parser = argparse.ArgumentParser(description='A tiny file extractor.')
    parser.add_argument('-x', '--extract', action='store_true',
                        help='Start the extraction on startup')
    parser.add_argument('-l', '--list', action='store_true',
                        help='Show the archive content')
    parser.add_argument('-q', '--quit', action='store_true',
                        help='Quit when the extraction is completed')
    parser.add_argument('-L', '--license', action='store_true')
    parser.add_argument('archive', nargs='?')
    parser.add_argument('destination', nargs='?')
    args = parser.parse_args()

    if args.license is True:
        from epack.utils import LICENSE
        import re
        rec = re.compile(r'<[^>]+>')
        print(re.sub(rec,'', LICENSE))
        sys.exit(0)

    elementary.init()
    app = EpackApplication(args)
    elementary.run()
    elementary.shutdown()
