#!/usr/bin/python3
# encoding=utf-8
#
# Copyright © 2015-2016 Simon McVittie <smcv@debian.org>
# Copyright © 2015-2016 Alexandre Detiste <alexandre@detiste.be>
# SPDX-License-Identifier: GPL-2.0-or-later

import configparser
import logging
import os
import subprocess

from ..build import (PackagingTask)
from ..game import (GameData)
from ..paths import DATADIR
from ..util import (mkdir_p)

logger = logging.getLogger(__name__)

def install_data(from_, to):
    subprocess.check_call(['cp', '--reflink=auto', from_, to])

class ScummvmGameData(GameData):
    def __init__(self, shortname, data):
        super(ScummvmGameData, self).__init__(shortname, data)

        self.wikibase = 'http://wiki.scummvm.org/index.php/'
        assert self.wiki

        if 'gameid' in self.data:
            self.gameid = self.data['gameid']
            assert self.gameid != shortname, 'extraneous gameid for ' + shortname
            self.aliases.add(self.gameid)
        else:
            self.gameid = shortname

        if self.engine is None:
            self.engine = 'scummvm'
        if self.genre is None:
            self.genre = 'Adventure'

    def _populate_package(self, package, d):
        super(ScummvmGameData, self)._populate_package(package, d)
        package.gameid = d.get('gameid')

    def construct_task(self, **kwargs):
        return ScummvmTask(self, **kwargs)

class ScummvmTask(PackagingTask):
    def iter_extra_paths(self, packages):
        super(ScummvmTask, self).iter_extra_paths(packages)

        gameids = set()
        for p in packages:
            gameid = p.gameid or self.game.gameid
            if gameid == 'agi-fanmade':
                continue
            gameids.add(gameid.split('-')[0])
        if not gameids:
            return

        # http://wiki.scummvm.org/index.php/User_Manual/Configuring_ScummVM
        # https://github.com/scummvm/scummvm/pull/656
        config_home = os.environ.get('XDG_CONFIG_HOME', os.path.expanduser('~/.config'))
        for rcfile in (os.path.join(config_home, 'scummvm/scummvm.ini'),
                       os.path.expanduser('~/.scummvmrc'),
                       os.path.join(config_home, 'residualvm/residualvm.ini'),
                       os.path.expanduser('~/.residualvmrc')):
            if os.path.isfile(rcfile):
                config = configparser.ConfigParser(strict=False)
                config.read(rcfile, encoding='utf-8')
                for section in config.sections():
                    for gameid in gameids:
                        if section.split('-')[0] == gameid:
                            if 'path' not in config[section]:
                                # invalid .scummvmrc
                                continue
                            path = config[section]['path']
                            if os.path.isdir(path):
                                yield path

    def fill_extra_files(self, per_package_state):
        super().fill_extra_files(per_package_state)
        package = per_package_state.package
        destdir = per_package_state.destdir

        if package.type not in ('demo', 'full') and not package.gameid:
            return

        icon = package.name
        for from_ in (self.locate_steam_icon(package),
                      os.path.join(DATADIR, package.name + '.png'),
                      os.path.join(DATADIR, self.game.shortname + '.png'),
                      os.path.join('/usr/share/pixmaps', icon + '.png'),
                      os.path.join(DATADIR,
                          self.game.shortname.strip('1234567890') + '.png')):
            if from_ and os.path.exists(from_):
                pixdir = os.path.join(destdir, 'usr/share/pixmaps')
                mkdir_p(pixdir)
                install_data(from_, os.path.join(pixdir, '%s.png' % icon))
                break
        else:
            icon = 'scummvm'

        from_ = os.path.splitext(from_)[0] + '.svgz'
        if os.path.exists(from_):
            svgdir = os.path.join(destdir, 'usr/share/icons/hicolor/scalable/apps')
            mkdir_p(svgdir)
            install_data(from_, os.path.join(svgdir, '%s.svgz' % icon))

        appdir = os.path.join(destdir, 'usr/share/applications')
        mkdir_p(appdir)

        desktop = configparser.RawConfigParser()
        desktop.optionxform = lambda option: option
        desktop['Desktop Entry'] = {}
        entry = desktop['Desktop Entry']
        entry['Name'] = package.longname or self.game.longname
        entry['GenericName'] = self.game.genre + ' Game'
        entry['TryExec'] = 'scummvm'
        entry['Icon'] = icon
        entry['Terminal'] = 'false'
        entry['Type'] = 'Application'
        entry['Categories'] = 'Game;%sGame;' % self.game.genre.replace(' ','')
        gameid = package.gameid or self.game.gameid
        install_to = self.packaging.substitute(package.install_to,
                                               package.name)
        if len(package.langs) == 1:
            entry['Exec'] = 'scummvm -p %s %s' % (
                    os.path.join('/', install_to), gameid)
            per_package_state.lintian_overrides.add(
                'desktop-command-not-in-package {} '
                '[usr/share/applications/{}.desktop]'.format(
                    'scummvm', package.name,
                )
            )
        else:
            pgm = package.name[0:len(package.name)-len('-data')]
            entry['Exec'] = pgm
            bindir = self.packaging.substitute(self.packaging.BINDIR, package.name)
            bindir = os.path.join(destdir, bindir.strip('/'))
            assert bindir.startswith(destdir + '/'), (bindir, destdir)
            mkdir_p(bindir)
            path = os.path.join(bindir, pgm)
            if 'en' not in package.langs:
                package.langs.append('en')
            with open(path, 'w') as f:
                f.write('#!/bin/sh\n')
                f.write('GAME_LANG=$(\n')
                f.write("echo $LANGUAGE $LANG en | tr ': ' '\\n' | cut -c1-2 | while read lang\n")
                f.write('do\n')
                for lang in package.langs:
                    f.write('[ "$lang" = "%s" ] && echo $lang && break\n' % lang)
                f.write('done\n')
                f.write(')\n')
                f.write('if [ "$GAME_LANG" = "en" ]; then\n')
                f.write('  exec scummvm -p %s %s\n' % (
                    os.path.join('/', install_to), gameid))
                f.write('else\n')
                f.write('  exec scummvm -q $GAME_LANG -p %s %s\n' % (
                    os.path.join('/', install_to), gameid))
                f.write('fi\n')
            os.chmod(path, 0o755)

        with open(os.path.join(appdir, '%s.desktop' % package.name),
                  'w', encoding='utf-8') as output:
             desktop.write(output, space_around_delimiters=False)

GAME_DATA_SUBCLASS = ScummvmGameData
