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

# Usage:
# out/run-tool-uninstalled tools/babel.py
# rsync -P out/available.html
#          illusion.pseudorandom.co.uk:/srv/game-data-packager.debian.net/www/available.html

# Online at https://game-data-packager.debian.net/available.html

from __future__ import annotations

import os
from typing import Optional

from game_data_packager.build import (FillResult)
from game_data_packager.game import (load_games)

SHOPS = [
   ('url_steam', 'Steam',
    'https://steamcommunity.com/groups/debian_gdp#curation'),
   ('url_gog', 'GOG.com', None),
   ('url_misc', 'Misc.', None)
]


class Game:
    todo: bool = False
    total: int = 0
    demos: int = 0
    langs: dict[str, int]
    missing_langs: set[str]
    multi_langs: set[str]
    genre: str = 'Unknown'
    year: Optional[int] = None
    franchise: Optional[str] = None
    shortname: str
    longname: str
    # free-as-in-beer
    fullfree: bool = True
    somefree: bool = False
    url_wiki: Optional[str] = None
    url_wikipedia: Optional[str] = None
    url_steam: Optional[str] = None
    url_gog: Optional[str] = None
    url_misc: Optional[str] = None

    def __init__(self, shortname: str) -> None:
        self.shortname = ''
        for char in shortname.lower():
            if 'a' <= char <= 'z' or '0' <= char <= '9':
                self.shortname += char
        self.langs = dict()
        self.missing_langs = set()
        self.multi_langs = set()

    def __repr__(self) -> str:
        return '<%s:%s>' % (self.genre, self.shortname)

    def __lt__(self, other: Game) -> bool:
        if self.genre < other.genre:
            return True
        elif self.genre > other.genre:
            return False

        if self.franchise and self.year:
            self_sort_key = '%s %d%s' % (
                self.franchise.lower(), self.year, self.shortname,
            )
        else:
            self_sort_key = self.shortname

        if other.franchise and other.year:
            other_sort_key = '%s %d%s' % (
                other.franchise.lower(), other.year, other.shortname,
            )
        else:
            other_sort_key = other.shortname

        return self_sort_key < other_sort_key


def load_stats() -> list[Game]:
    games: list[Game] = []

    for name, game in load_games().items():
        g = Game(name)
        g.genre = game.genre or 'Unkown'
        g.franchise = game.franchise
        g.longname = game.longname
        g.missing_langs = set(game.missing_langs)
        g.url_wikipedia = game.wikipedia
        g.url_wiki = game.wikibase + (game.wiki or '')
        g.url_steam = game.url_steam
        g.url_gog = game.url_gog
        g.url_misc = game.url_misc

        if game.copyright:
            g.year = int(game.copyright[2:6])

        for package in game.packages.values():
            g.total += 1

            if package.copyright:
                year = int(package.copyright[2:6])
                if not g.year:
                    g.year = year
                else:
                    g.year = min(g.year, year)

            if package.demo_for:
                g.demos += 1
            else:
                g.langs[package.lang] = g.langs.get(package.lang, 0) + 1
                g.multi_langs.update(set(package.langs))

            with game.construct_task() as task:
                if task.fill_gaps(
                    package=package, log=False,
                ) is FillResult.IMPOSSIBLE:
                    if not package.better_versions:
                        g.fullfree = False
                else:
                    g.somefree = True

        games.append(g)

    return games


games = load_stats()


# add missing games from list
def load_todo() -> list[Game]:
    games: list[Game] = list()

    with open('debian/TODO', 'r', encoding='utf8') as missing:
        for line in missing:
            if line[0:2] == '##':
                break

        genre = 'Unknown'
        for line in missing:
            line = line.strip()
            if line[0:1] == '#':
                genre = line[1:len(line)].strip()
                continue
            elif line == '':
                continue

            if '#' in line:
                longname, bug = line.split('#')
                if ' ' in bug:
                    bug, remainder = bug.split(maxsplit=1)
                else:
                    remainder = ''
                shortname = longname
                longname = (
                    '%s <a href="https://bugs.debian.org/'
                    'cgi-bin/bugreport.cgi?bug=%s">#%s</a> %s'
                ) % (longname, bug, bug, remainder)
            elif 'http://' in line or 'https://' in line:
                shortname = line
                longname = line   # TODO
            else:
                shortname = line
                longname = line

            g = Game(shortname)
            g.todo = True
            g.fullfree = False
            g.genre = genre
            g.longname = longname

            games.append(g)
    return games


games += load_todo()

# compute totals
langs: dict[str, int] = dict()
genres: dict[str, int] = dict()
for game in games:
    genres[game.genre] = genres.get(game.genre, 0) + 1
    for lang, count in game.langs.items():
        langs[lang] = langs.get(lang, 0) + count

games.sort()

output = os.path.join(os.environ.get('GDP_BUILDDIR', 'out'), 'available.html')

html = open(output, 'w', encoding='utf8')
html.write('''\
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Game-Data-Packager</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<meta name="generator" \
content="https://salsa.debian.org/games-team/game-data-packager/\
tree/master/tools/babel.py">
<style type="text/css">
''')

all_langs = sorted(langs.keys())
for lang in all_langs:
    if lang == 'en':
        continue
    html.write('  #check-%s:checked ~ * .%s' % (lang, lang))
    if lang != all_langs[-1]:
        html.write(',\n')

html.write(''' {
  background-color: yellow;
}
</style>
</head>

<body>
<h1>Debian Games Team</h1>
<img src="../proposed-logo.png" height="64" width="64"
 alt="Debian Games Team logo">
<h2>List of games supported by <code>game-data-packager</code> in git</h2>
This is an automaticaly generated list of games supported by the
upcoming release.<br>
Please visit the
<a href="http://wiki.debian.org/Games/GameDataPackager">Wiki</a>
for more general information.
<br><br>
''')

langs_order = [
    k
    for k, v in sorted(langs.items(), key=lambda kv: (-kv[1], kv[0]))
]
for lang in langs_order:
    if lang == 'en':
        continue
    html.write(
        '<!--label for=check-%s-->%s<!--/label-->'
        '<input id=check-%s type=checkbox>&nbsp;&nbsp;'
        % (lang, lang, lang)
    )

html.write('''<table border=1 cellspacing=0>
<tr>
<td colspan=2>&nbsp</td>
<td>WP</td>
<td>yaml</td>
<td><b>Total</b></td>
''')

for lang in langs_order:
    html.write('  <td><b>%s</b></td>\n' % lang)
html.write('<td>Demo</td>')
for _, name, url in SHOPS:
    if url:
        html.write('<td><a href="%s">%s</a></td>' % (url, name))
    else:
        html.write('<td>%s</td>' % name)
html.write('</tr>')


# BODY
def body() -> tuple[int, int]:
    last_genre = None
    total = 0
    demos = 0
    wikipedia = set()
    for game in games:
        total += game.total
        html.write('<tr>\n')
        genre = game.genre
        if genre != last_genre:
            html.write('<td rowspan=%i>%s</td>\n' % (genres[genre], genre))
            last_genre = genre
        highlight = [
            lang
            for lang in langs_order
            if lang != 'en' and lang in game.langs
        ]
        highlight += list(game.missing_langs)
        if highlight:
            css = ' class="%s"' % ' '.join(highlight)
        else:
            css = ''
        html.write('  <td%s>' % css)
        if game.url_wiki:
            html.write('<a href="%s">%s</a>' % (game.url_wiki, game.longname))
        else:
            html.write(game.longname)
        html.write('</td>')

        wp = game.url_wikipedia
        if wp in wikipedia:
            html.write('<td><b>&Prime;</b></td>')
        elif wp:
            html.write('<td><a href="%s"><b>W</b></a></td>' % wp)
            wikipedia.add(wp)
        else:
            html.write('<td>&nbsp;</td>')

        if game.todo:
            html.write('<td>&nbsp;</td>')
            html.write('  <td bgcolor="orange">!</td>\n')
        else:
            html.write('<td><a href="https://salsa.debian.org/games-team/'
                       'game-data-packager/tree/master/data/%s.yaml">'
                       '⌨</a></td>' % game.shortname)
            html.write('  <td bgcolor="lightgreen">%s</td>\n' % game.total)

        for lang in langs_order:
            count = game.langs.get(lang, 0)
            if count and lang == 'en':
                html.write('  <td bgcolor="lightgreen">%s</td>\n' % count)
            elif count:
                html.write('  <td bgcolor="green">%s</td>\n' % count)
            elif lang in game.multi_langs:
                html.write('  <td bgcolor="lightgreen">*</td>\n')
            elif lang in game.missing_langs:
                html.write('  <td bgcolor="orange">!</td>\n')
            else:
                html.write('  <td>&nbsp;</td>\n')

        if game.fullfree:
            html.write(
                '  <td colspan=%d align=center%s><b>freeload</b></td>\n'
                % (len(SHOPS) + 1, css)
            )
        else:
            if game.demos:
                demos += game.demos
                html.write('  <td align=center><b>%i</b></td>\n' % game.demos)
            elif game.somefree:
                html.write('  <td align=center><b>X</b></td>\n')
            else:
                html.write('  <td>&nbsp;</td>\n')
            for u in (game.url_steam, game.url_gog, game.url_misc):
                if u:
                    html.write(
                        '  <td align=center%s><a href="%s"><b>X</b></a></td>\n'
                        % (css, u)
                    )
                else:
                    html.write('  <td%s>&nbsp;</td>\n' % css)
        html.write('</tr>\n')

    return (total, demos)


total, demos = body()

# TOTAL
html.write('<tr><td colspan=4><b>Total</b></td>\n')
html.write('  <td><b>%i</b></td>\n' % total)
for lang in langs_order:
    html.write('  <td><b>%i</b></td>\n' % langs[lang])

html.write('  <td><b>%i</b></td>\n' % demos)

html.write('''<td colspan=%s>&nbsp;</td>
</tr>
</table>
<ul>
<li>! : language is missing</li>
<li>* : multi-lang support in a single package</li>
</ul>
</body>
</html>
''' % len(SHOPS)
)

html.close()
