#!/usr/bin/env python

# Copyright (C) 2012 Aleksey Lim
#
# 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 os
import re
import sys
from os.path import join
from gettext import gettext as _

from sweets_distribution.pms import Pms
from sweets_distribution import printf, application
from sweets_distribution.options import Option
from sweets_distribution.application import Application, command
from sweets_distribution.util import enforce


class Application(application.Application):

    @application.command(
            _('current repository status information'))
    def status(self):
        pms = Pms()

        printf.dump(_('Platform') + ':')
        printf.dump('   %s-%s', pms.distro_id, pms.distro_rel)
        printf.dump('')

        printf.dump(_('Repositories') + ':')
        if pms.plugged_repo:
            printf.dump('   %s' % pms.plugged_repo)
        else:
            printf.dump('   (%s)' % _('no'))
        printf.dump('')

        to_sync = []
        for package in pms.to_sync():
            to_sync.append(str(package))
        if not to_sync and pms.plugged_repo and \
                (pms.new_config or not pms.has_keys()):
            to_sync.append('(%s)' % _('yes'))
        if to_sync:
            printf.hint(_('Use "sync" command to synchronize packages'))
        printf.dump(_('Need to sync:'))
        for i in to_sync or ['(%s)' % _('no')]:
            printf.dump('   %s' % i)

        printf.dump('')
        printf.dump(_('Available repositories') + ':')
        has_repos = False
        for repo, distro_id, distro_rel in pms.fetch_repos():
            if distro_id == pms.distro_id and distro_rel == pms.distro_rel:
                printf.dump('   %s', repo)
                has_repos = True
        if not has_repos:
            printf.dump('   (%s)', _('no'))
        elif not pms.plugged_repo:
            printf.hint(_('Use "select" command to start using ' \
                    'one of available repositories'))

        __, rel = pms.resolve_package('sweets-desktop')
        if not rel:
            printf.hint(_('Instlall "sweets-desktop" package ' \
                    'to have Sweets Desktop'))

    @application.command(
            _('make sure that currently installed packages come from '
                'selected repository'))
    def sync(self):
        enforce_root()

        pms = Pms()
        pms.ensure_config()

        to_uninstall = []
        to_install = []

        for package in pms.to_sync():
            if package.downgrade:
                to_uninstall.append(package)
            to_install.append(package)

        pms.update()
        pms.uninstall(to_uninstall)
        pms.install(to_install)

    @application.command(
            _('register specified repository in the system'),
            args='REPO [DISTRO]')
    def select(self):
        enforce_root()
        enforce(self.args, _('Specify repository to select'))

        repo = self.args.pop(0)
        pms = Pms()

        distro_rel = pms.distro_rel
        if self.args:
            arg = self.args[0].split('-')[-1]
            if re.match('[0-9.]+$', arg):
                distro_rel = arg
                self.args.pop(0)

        pms.select(repo, distro_rel)

        printf.hint(_('Use "status" command for getting status after ' \
                'selecting new repository'))
        printf.hint(_('Use "sync" command to make sure that installed ' \
                'packages are the same as in newly selected repository'))

    @application.command(
            _('unregister current repository'))
    def clean(self):
        enforce_root()
        Pms().clean()

    @application.command(hidden=True)
    def install(self):
        enforce_root()
        Pms().self_install()
        printf.hint(_('Run "sweets-distribution -h" for getting help'))

    @application.command(hidden=True, name='repo-config')
    def repo_config(self):
        enforce(self.args, 'Specify repository')
        repo = self.args.pop(0)
        distro_rel = self.args.pop(0) if self.args else None
        sys.stdout.write(Pms().config(repo, distro_rel))

    @application.command(hidden=True, name='import-keys')
    def import_keys(self):
        distro_rel = self.args.pop(0) if self.args else None
        Pms().import_pubkey(distro_rel)


def enforce_root():
    if os.getuid() != 0:
        printf.hint(_('Re-run command with prefixing it with "sudo" command'))
        raise RuntimeError(_('Command should be launched from the root user'))


Option.seek('main', [application.debug, application.no_hints])

config_files = [
        '/etc/sweets.conf',
        '~/.config/sweets/config',
        ]
if 'HOME' in os.environ:
    profile_config = join(os.environ['HOME'], '.sugar',
            os.environ.get('SUGAR_PROFILE', 'default'), 'sweets.conf')
    config_files.append(profile_config)

application = Application(
        name='sweets-distribution',
        description=_('Manage Sweets Distribution repositories.'),
        epilog=_('See http://wiki.sugarlabs.org/go/Sweets_Distribution '
            'for details'),
        config_files=config_files)
application.start()
