#!/usr/bin/python3
# encoding=utf-8
#
# Copyright © 2024 Sébastien Noel <sebastien@twolife.be>
# SPDX-License-Identifier: GPL-2.0-or-later

from __future__ import annotations

import glob
import logging
import os
import subprocess
from typing import (TYPE_CHECKING)
from zipfile import ZipFile

from ..build import (FillResult, PackagingTask)
from ..game import (GameData)
from ..util import (mkdir_p)

if TYPE_CHECKING:
    from typing import (Unpack)
    from ..data import (Package)
    from ..packaging import (PerPackageState, PackagingTaskArgs)

logger = logging.getLogger(__name__)


class SC3UGameData(GameData):
    def construct_task(self, **kwargs: Unpack[PackagingTaskArgs]) -> SC3UShim:
        return SC3UShim(self, **kwargs)


class SC3UShim(PackagingTask):
    def fill_gaps(
        self,
        package: Package | None,
        download: bool = False,
        log: bool = True,
        recheck: bool = False,
        requested: bool = False,
    ) -> FillResult:
        assert package is not None

        arch = self.builder_packaging.get_architecture()
        if arch not in ['amd64', 'i386']:
            logger.warning('Cross-compiling %s from %s not supported',
                           package.name, arch)
            return FillResult.IMPOSSIBLE

        return super().fill_gaps(
            package,
            download=download,
            log=log,
            recheck=recheck,
            requested=requested,
        )

    def fill_extra_files(
        self,
        per_package_state: PerPackageState
    ) -> None:
        super().fill_extra_files(per_package_state)
        package = per_package_state.package
        destdir = per_package_state.destdir

        if package.name == 'sc3u-data':
            # The game need these 2 empty directories
            gamedir = os.path.join(destdir, 'usr', 'share',
                                   'games', self.game.shortname)
            mkdir_p(os.path.join(gamedir, 'res/ba/ui/shared/dlg'))
            mkdir_p(os.path.join(gamedir, 'res/sound/radio/stations'))
            return

        if package.name != 'sc3u-bin':
            return

        # Extract, build & install the shim
        install_dir = os.path.join(destdir, 'usr', 'lib', self.game.shortname)
        unpackdir = os.path.join(
            self.get_workdir(), 'tmp', package.name + '.build.d',
        )

        zipname = os.path.join(destdir, 'usr', 'share',
                                        'games', self.game.shortname,
                                        'sc3u-nptl.zip')
        with ZipFile(zipname) as zObject:
            zObject.extractall(path=unpackdir)

        expect_dir_list = list(glob.glob(os.path.join(unpackdir, '*')))
        assert len(expect_dir_list) == 1, expect_dir_list
        expect_dir = os.path.basename(expect_dir_list[0])

        subprocess.check_call([
            'make', '-C',
            os.path.join(unpackdir, expect_dir), '-s',
        ])
        subprocess.check_call([
            'install', '-s', '-m644',
            os.path.join(unpackdir, expect_dir, 'sc3u-nptl.so'),
            os.path.join(install_dir, 'sc3u-nptl.so'),
        ])


GAME_DATA_SUBCLASS = SC3UGameData
