from __future__ import print_function, unicode_literals
import re
from bs4 import BeautifulSoup
from django.core.files import File
from django.core.management import BaseCommand
from io import BytesIO
from wand.exceptions import WandException
import requests
from pic.models import (
    Flag,
    SOVEREIGN_STATE,
    UNRECOGNISED_STATE,
    EXTINCT_STATE,
)


class Command(BaseCommand):
    help = 'Fetch urls for flags from Wikimedia'

    def handle(self, *args, **options):
        state_types = {
            SOVEREIGN_STATE: iter_sovereign_flags,
            UNRECOGNISED_STATE: iter_unrecognised_flags,
            EXTINCT_STATE: iter_extinct_flags,
        }
        for state_type, func in state_types.items():
            for state, url in func():
                print(state)
                svg = requests.get(url).content
                try:
                    thumb = Flag.mkthumb(svg)
                except WandException as err:
                    # SVG probably missing XML declaration
                    svg = b"<?xml version='1.0' encoding='ASCII'?>\n" + svg
                    thumb = Flag.mkthumb(svg)
                with BytesIO(svg) as svg_io, BytesIO(thumb) as thumb_io:
                    flag = Flag(
                        state=state,
                        state_type=state_type,
                        svg=File(svg_io, name=snake(state) + '.svg'),
                        thumb=File(thumb_io, name=snake(state) + '_thumb.png'),
                        sort_key=Flag.mksort_key(state),
                    )
                    flag.save()


def iter_flags(proto, base_url, page):
    state_re = re.compile(
        r"^(?:First |Second |Last )?Flag of (?:the )?([\w :'-]+)"
    )
    strip_w_re = re.compile(r'\bw:')
    wiki_resp = requests.get(proto + base_url + page)
    wiki_soup = BeautifulSoup(wiki_resp.text, 'html.parser')
    for a_img in wiki_soup.find_all('a', {'class': 'image'}):
        match = state_re.match(a_img['title'])
        if match:
            state = match.group(1)
        else:
            print('Unable to parse flag title "{}"'.format(a_img['title']))
            state = a_img['title']
        state = strip_w_re.sub('', state).strip()
        svg_resp = requests.get(proto + base_url + a_img['href'])
        svg_soup = BeautifulSoup(svg_resp.text, 'html.parser')
        a_svg = svg_soup.find('a', {'class': 'internal'})
        svg_url = a_svg['href'] if a_svg['href'].startswith('http') \
            else proto + a_svg['href']
        yield state, svg_url


def iter_sovereign_flags():
    proto = 'https:'
    base_url = '//en.wikipedia.org'
    page = '/wiki/Gallery_of_sovereign_state_flags'
    for state, url in iter_flags(proto, base_url, page):
        yield state, url


def iter_unrecognised_flags():
    proto = 'https:'
    base_url = '//commons.wikimedia.org'
    page = '/wiki/Flags_of_unrecognized_states'
    for state, url in iter_flags(proto, base_url, page):
        yield state, url


def iter_extinct_flags():
    proto = 'https:'
    base_url = '//commons.wikimedia.org'
    page = '/wiki/Flags_of_extinct_states'
    for state, url in iter_flags(proto, base_url, page):
        yield state, url


def snake(title_case):
    return title_case.replace(' ', '_').lower()
