#!/usr/bin/python3

import argparse
import locale
import puz
import requests
import os
import sys

locale.setlocale(locale.LC_ALL, "")

NIENTEPERNIENTE_BASE = "https://www.nienteperniente.it"

NIENTEPERNIENTE_PUZZLES = {
    165: "en_13_natale/165alfanumerico5x5.puz",
    173: "en_16_inverno/20160115Cruciverba15x15_Schema_libero.puz",
    174: "en_16_inverno/20160117Cruciverba15x15_Schema_libero.puz",
    175: "en_16_inverno/20160130Cruciverba5x5_Animali.puz",
    176: "en_16_inverno/20160129Cruciverba5x5_Animali.puz",
    177: "en_16_inverno/20160129Cruciverba5x5_Citta_italiane.puz",
    178: "en_16_inverno/20160129Cruciverba5x5_I_5_sensi.puz",
    179: "en_16_primavera/20160120Cruciverba15x15-Citta_italiane.puz",
    180: "en_16_primavera/20160814Cruciverba15x15.puz",
    181: "en_16_primavera/20160820Cruciverba5x5.puz",
    182: "en_16_primavera/20160821Cruciverba5x5.puz",
    183: "en_16_primavera/20160916Cruciverba15x15.puz",
    184: "en_16_primavera/20160918Cruciverba10x10.puz",
    185: "en_16_autunno/20160930Cruciverba10x10.puz",
    186: "en_16_autunno/20180116Cruciverba5x5-20160116.puz",
    187: "en_16_autunno/20180116Cruciverba5x5-20160117.puz",
    188: "en_16_autunno/20180116Cruciverba5x5-20160118.puz",
    189: "en_16_autunno/20180116Cruciverba5x5-20160119.puz",
    190: "en_16_autunno/20180116Cruciverba5x5-20160120.puz",
    191: "en_17_inverno/20161011Cruciverba10x10.puz",
    192: "en_17_inverno/20161015Cruciverba15x15-Attori_cinematografici.puz",
    193: "en_17_inverno/20170923Cruciverba5x5.puz",
    195: "en_17_inverno/20180116Cruciverba5x5.puz",
    196: "en_17_inverno/20180117Cruciverba5x5.puz",
    197: "en_18_febbraio/20180124_Cruciverba15x15.puz",
    198: "en_18_febbraio/20180128_Cruciverba5x5_-_1.puz",
    199: "en_18_febbraio/20180128_Cruciverba5x5_-_2.puz",
    200: "en_18_febbraio/20180128_Cruciverba5x5_-_3.puz",
    201: "en_18_febbraio/20180129_Cruciverba5x5_-_20160816.puz",
    202: "en_18_febbraio/20180131_Cruciverba5x5_-_20160816.puz",
    206: "en_18_primavera/20180204_Cruciverba10x10.puz",
    207: "en_18_primavera/20180205_Cruciverba9x9-20171229.puz",
    208: "en_18_primavera/20180226_Cruciverba9x9-Schema_definito.puz",
    209: "en_19_dicembre/20191226_Alfanumerico5x5.puz",
    210: "en_19_dicembre/20191226_Cruciverba5x5.puz",
    211: "en_19_dicembre/20191226_Cruciverba6x6.puz",
    212: "en_19_dicembre/20191227_Cruciverba5x5.puz",
    213: "en_19_dicembre/20191227_Cruciverba6x6.puz",
    214: "en_19_dicembre/20191228_Cruciverba5x5.puz",
    215: "en_20_inverno/20191229_Cruciverba5x5.puz",
    216: "en_20_inverno/20191229_Cruciverba10x10.puz",
    217: "en_20_inverno/20191230_Cruciverba5x5.puz",
    218: "en_20_inverno/20191230_Cruciverba6x6.puz",
    219: "en_20_inverno/20191231_Cruciverba5x5.puz",
    220: "en_20_inverno/20191231_Cruciverba6x6.puz",
    221: "enigmistica/20200805_Cruciverba6x6.puz",
    222: "enigmistica/20200807_Cruciverba5x5.puz",
    223: "enigmistica/20200812_Cruciverba5x5.puz",
    224: "enigmistica/20200817_Cruciverba5x5.puz",
    225: "enigmistica/20200818_Cruciverba5x5.puz",
    226: "enigmistica/20200830_Cruciverba5x8.puz",
    227: "enigmistica/20200808_Cruciverba6x6.puz",
    228: "enigmistica/20200820_Cruciverba5x7.puz",
    229: "enigmistica/20200831_Cruciverba8x13.puz",
    230: "enigmistica/20200903_Cruciverba5x8.puz",
    231: "enigmistica/20200902_Cruciverba8x13.puz",
    232: "enigmistica/20201224_Cruciverba5x5.puz",
    233: "enigmistica/20200918_Cruciverba8x13.puz",
    234: "enigmistica/20201229_Cruciverba5x5.puz",
    235: "enigmistica/20210101_Cruciverba5x5.puz",
    236: "enigmistica/20210101_Cruciverba5x8.puz",
    237: "enigmistica/20210102_Cruciverba5x5.puz",
    238: "enigmistica/20210102_Cruciverba5x8.puz",
    239: "enigmistica/20210103_Cruciverba5x5.puz",
    240: "enigmistica/20210103_Cruciverba5x8.puz",
    241: "enigmistica/20210110_Cruciverba5x9.puz",
    242: "enigmistica/20210212_Cruciverba5x9.puz",
    243: "enigmistica/20210214_Cruciverba5x9.puz",
    244: "enigmistica/20210309_Cruciverba9x9.puz",
    245: "enigmistica/20210310_Cruciverba6x9.puz",
    246: "enigmistica/20210513_Cruciverba6x8.puz",
}


class InvalidNumberException(Exception):
    pass


class PuzDownloader:
    def getPuzzle(self, number):
        if number not in NIENTEPERNIENTE_PUZZLES.keys():
            raise InvalidNumberException

        r = requests.get(f"{NIENTEPERNIENTE_BASE}/{NIENTEPERNIENTE_PUZZLES[number]}")
        puzzle = r.content

        # Some of these puzzles all have the same title, prefix the number so
        # we can tell them apart.
        p = puz.load(puzzle)
        orig_title = p.title
        p.title = f"[{number:02d}] {orig_title}"

        return p.tobytes()


def main():
    parser = argparse.ArgumentParser(
        description="fetch .puz files from https://www.nienteperniente.it"
    )
    parser.add_argument("number", type=int)
    args = parser.parse_args()

    downloader = PuzDownloader()
    try:
        puzzle = downloader.getPuzzle(args.number)
    except InvalidNumberException:
        print("Invalid puzzle number")
        sys.exit(1)

    # Can't just use print() here as puzzle is bytes, not a string
    with os.fdopen(sys.stdout.fileno(), "wb", closefd=False) as stdout:
        stdout.write(puzzle)
        stdout.flush()

    sys.exit(0)


if __name__ == "__main__":
    main()
