import datetime
import re


def trim_space(input_str):
    result = re.sub(' {2,}', ' ', input_str)
    return result


class EnParser:
    def trim_ref(self, input_str):
        result = re.sub('\[\d{1,3}\]', '', input_str)
        result = re.sub('\[Note \d{1,3}\]', '', result)
        result = re.sub('\[\w{1}\]', '', result)
        return result

    def parse_infobox_info(self, _selector):
        _photo = []
        _infobox_dict = {}
        infobox_table_lines = _selector.xpath("//table[contains(@class,'infobox')]/tbody/tr")
        for line in infobox_table_lines:
            if len(_photo) == 0:
                flag_images = line.xpath(".//img")
                if len(flag_images) > 0:
                    _photo = [img.attrib['src'] for img in flag_images]
            td = line.xpath(".//td")
            if len(td) > 1:
                th_text_list = td[0].xpath(".//text()")
                th_text = self.filter_text_list(th_text_list)
                td_text_list = td[1].xpath(".//text()")
                td_text = self.filter_text_list(td_text_list)
                _infobox_dict[th_text] = td_text
            elif len(td) == 1:
                th = line.xpath(".//th")
                if len(th) > 0:
                    th_text_list = th[0].xpath(".//text()")
                    th_text = self.filter_text_list(th_text_list)
                    td_text_list = td[0].xpath(".//text()")
                    td_text = self.filter_text_list(td_text_list)
                    _infobox_dict[th_text] = td_text
        return _photo, _infobox_dict

    def parse_toc(self, _selector):
        _toc = []
        toc_lines = _selector.xpath(
            "//div[@id='vector-toc']//div[@class='vector-toc-text']")
        for toc_line in toc_lines:
            toc_line_text = toc_line.xpath("./text()")
            toc_line_num = toc_line.xpath("./span/text()")
            _trim_content = []
            for _ in toc_line_text:
                _ = _.replace("\n", "").strip()
                if '.mw-parser-output' not in _:
                    _trim_content.append(_)
            _toc.append(''.join(toc_line_num) + ' ' + " ".join(_trim_content))
        return _toc

    def parse_contents(self, _selector):
        _contents = []
        content_lines = _selector.xpath("//div[@id='mw-content-text']/div[@class='mw-parser-output']/*")
        paragraph_content_list = []
        paragraph_tag = ''
        paragraph_header = ''
        paragraph_note = []
        paragraph_images = []
        paragraph_tables = []
        for content_line in content_lines:
            if content_line.tag in ['table']:
                if 'class' in content_line.attrib and content_line.attrib['class'] in ['wikitable', 'infobox']:
                    table_lines = content_line.xpath("./tbody/tr")
                    ths = []
                    table_contents = []
                    for line in table_lines:
                        if len(ths) == 0:
                            th_list = line.xpath("./th")
                            for th in th_list:
                                th_text_list = th.xpath(".//text()")
                                th_text = self.filter_text_list(th_text_list)
                                if len(th_text) > 0:
                                    ths.append(th_text)
                        else:
                            td_list = line.xpath("./td")
                            tds = []
                            for td in td_list:
                                td_text_list = td.xpath(".//text()")
                                td_text = self.filter_text_list(td_text_list)
                                tds.append(td_text)
                            if len(tds) == len(ths):
                                item = {}
                                for i in range(len(ths)):
                                    item[ths[i]] = tds[i]
                                table_contents.append(item)
                    paragraph_tables.append(table_contents)
            elif content_line.tag in ['div']:
                if 'class' in content_line.attrib and content_line.attrib['class'] == 'thumb tright':
                    images = content_line.xpath(".//img")
                    for image in images:
                        paragraph_images.append(image.attrib['src'])
                if 'role' in content_line.attrib and content_line.attrib['role'] == 'note':
                    note = content_line.xpath(".//text()")
                    note_text = self.filter_text_list(note)
                    paragraph_note.append(note_text)
            elif content_line.tag in ['p']:
                _content = content_line.xpath(".//text()")
                _content_text = self.filter_text_list(_content)
                paragraph_content_list.append(self.trim_ref(_content_text))
            elif content_line.tag in ['ul', 'ol']:
                li_list = content_line.xpath("./li")
                for li in li_list:
                    _content = li.xpath(".//text()")
                    _content_text = self.filter_text_list(_content)
                    if len(paragraph_content_list) == 0:
                        paragraph_content_list.append("\\n")
                    paragraph_content_list.append(self.trim_ref(_content_text))
            elif content_line.tag.startswith('h'):
                if paragraph_header == '':
                    paragraph_header = 'Intro'
                    paragraph_tag = 'h2'
                paragraph_text = '\\n        '.join(paragraph_content_list)
                content_item = {
                    'tag': paragraph_tag,
                    'header': paragraph_header
                }
                if len(paragraph_note) > 0:
                    content_item['note'] = paragraph_note
                if len(paragraph_text) > 0:
                    content_item['text'] = '        ' + paragraph_text
                if len(paragraph_images) > 0:
                    content_item['images'] = paragraph_images
                if len(paragraph_tables) > 0:
                    content_item['tables'] = paragraph_tables
                _contents.append(content_item)
                paragraph_content_list = []
                paragraph_images = []
                paragraph_tables = []
                paragraph_note = []
                _header = content_line.xpath(".//text()")[0]
                paragraph_header = self.trim_ref(_header)
                paragraph_tag = content_line.tag
        return _contents

    def parse_modified_time(self, _selector):
        _last_modified = _selector.xpath("//ul[@id='footer-info']/li[@id='footer-info-lastmod']")[0].text
        _last_modified = _last_modified[30:]
        m_date = _last_modified.split(", at ")[0]
        m_time = _last_modified.split(", at ")[1]
        date_obj = datetime.datetime.strptime(m_date, '%d %B %Y')
        m_date = date_obj.strftime('%Y-%m-%d')
        return m_date + ' ' + m_time

    def filter_text_list(self, text_list):
        _trim_content = []
        for _ in text_list:
            _ = _.replace("\n", "")
            _ = _.replace('"', '\\"')
            _ = _.replace("\xa0", "")
            _ = _.replace("\ufeff", "")
            _ = self.trim_ref(_)
            _ = _.strip()
            if '.mw-parser-output' not in _:
                _trim_content.append(_)
        return trim_space(" ".join(_trim_content))


class JpParser:
    def trim_ref(self, input_str):
        result = re.sub('\[\d{1,3}\]', '', input_str)
        result = re.sub('\[注 \d{1,3}\]', '', result)
        result = re.sub('\[\w{1}\]', '', result)
        return result

    def parse_infobox_info(self, _selector):
        _photo = []
        _infobox_dict = {}
        infobox_table_lines = _selector.xpath("//table[@class='infobox']/tbody/tr")
        for line in infobox_table_lines:
            _images = line.xpath(".//img")
            if len(_images) > 0:
                _photo += [img.attrib['src'] for img in _images]
            th = line.xpath(".//th")
            td = line.xpath(".//td")
            if len(th) > 0:
                th_text_list = th[0].xpath(".//text()")
                th_text = self.filter_text_list(th_text_list)
                td_text = ""
                if len(td) > 0:
                    td_text_list = td[0].xpath(".//text()")
                    td_text = self.filter_text_list(td_text_list)
                _infobox_dict[th_text] = td_text
        return _photo, _infobox_dict

    def parse_toc(self, _selector):
        _toc = []
        toc_lines = _selector.xpath(
            "//div[@id='vector-toc']//div[@class='vector-toc-text']")
        for toc_line in toc_lines:
            toc_line_text = toc_line.xpath("./text()")
            toc_line_num = toc_line.xpath("./span/text()")
            _trim_content = []
            for _ in toc_line_text:
                _ = _.replace("\n", "").strip()
                if '.mw-parser-output' not in _:
                    _trim_content.append(_)
            _toc.append(''.join(toc_line_num) + ' ' + " ".join(_trim_content))
        return _toc

    def parse_contents(self, _selector):
        _contents = []
        content_lines = _selector.xpath("//div[@id='mw-content-text']/div[@class='mw-parser-output']/*")
        paragraph_content_list = []
        paragraph_tag = ''
        paragraph_header = ''
        paragraph_note = []
        paragraph_images = []
        paragraph_tables = []
        for content_line in content_lines:
            if content_line.tag in ['table']:
                if 'class' in content_line.attrib and content_line.attrib['class'] in ['wikitable', 'infobox']:
                    table_lines = content_line.xpath("./tbody/tr")
                    ths = []
                    table_contents = []
                    for line in table_lines:
                        if len(ths) == 0:
                            th_list = line.xpath("./th")
                            for th in th_list:
                                th_text_list = th.xpath(".//text()")
                                th_text = self.filter_text_list(th_text_list)
                                if len(th_text) > 0:
                                    ths.append(th_text)
                        else:
                            td_list = line.xpath("./td")
                            tds = []
                            for td in td_list:
                                td_text_list = td.xpath(".//text()")
                                td_text = self.filter_text_list(td_text_list)
                                tds.append(td_text)
                            if len(tds) == len(ths):
                                item = {}
                                for i in range(len(ths)):
                                    item[ths[i]] = tds[i]
                                table_contents.append(item)
                    paragraph_tables.append(table_contents)
            elif content_line.tag in ['div']:
                if 'class' in content_line.attrib and content_line.attrib['class'] == 'thumb tright':
                    images = content_line.xpath(".//img")
                    for image in images:
                        paragraph_images.append(image.attrib['src'])
                if 'role' in content_line.attrib and content_line.attrib['role'] == 'note':
                    note = content_line.xpath(".//text()")
                    note_text = self.filter_text_list(note)
                    paragraph_note.append(note_text)
            elif content_line.tag in ['p']:
                _content = content_line.xpath(".//text()")
                _content_text = self.filter_text_list(_content)
                paragraph_content_list.append(self.trim_ref(_content_text))
            elif content_line.tag in ['ul', 'ol']:
                li_list = content_line.xpath("./li")
                for li in li_list:
                    _content = li.xpath(".//text()")
                    _content_text = self.filter_text_list(_content)
                    if len(paragraph_content_list) == 0:
                        paragraph_content_list.append("\\n")
                    paragraph_content_list.append(self.trim_ref(_content_text))
            elif content_line.tag.startswith('h'):
                if paragraph_header == '':
                    paragraph_header = '总体情况'
                    paragraph_tag = 'h2'
                paragraph_text = '\\n        '.join(paragraph_content_list)
                content_item = {
                    'tag': paragraph_tag,
                    'header': paragraph_header
                }
                if len(paragraph_note) > 0:
                    content_item['note'] = paragraph_note
                if len(paragraph_text) > 0:
                    content_item['text'] = '        ' + paragraph_text
                if len(paragraph_images) > 0:
                    content_item['images'] = paragraph_images
                if len(paragraph_tables) > 0:
                    content_item['tables'] = paragraph_tables
                _contents.append(content_item)
                paragraph_content_list = []
                paragraph_images = []
                paragraph_tables = []
                paragraph_note = []
                _header = content_line.xpath(".//text()")[0]
                paragraph_header = self.trim_ref(_header)
                paragraph_tag = content_line.tag
        return _contents

    def parse_modified_time(self, _selector):
        _last_modified = _selector.xpath("//ul[@id='footer-info']/li[@id='footer-info-lastmod']")[0].text
        _last_modified = _last_modified[6:-5]
        m_date = _last_modified.split("(")[0].replace("年", "-").replace("月", "-").replace("日", "")
        m_time = _last_modified.split(")")[1].strip() + ':00'
        return m_date + m_time

    def filter_text_list(self, text_list):
        _trim_content = []
        for _ in text_list:
            _ = _.replace("\n", "")
            _ = _.replace('"', '\\"')
            _ = _.replace("\xa0", "")
            _ = _.replace("\ufeff", "")
            _ = self.trim_ref(_)
            _ = _.strip()
            if '.mw-parser-output' not in _:
                _trim_content.append(_)
        return trim_space(" ".join(_trim_content))


class ZhParser:
    def trim_ref(self, input_str):
        result = re.sub('\[\d{1,3}\]', '', input_str)
        result = re.sub('\[注 \d{1,3}\]', '', result)
        result = re.sub('\[\w{1}\]', '', result)
        return result

    def parse_infobox_info(self, _selector):
        _photo = []
        _infobox_dict = {}
        infobox_table_lines = _selector.xpath("//table[@class='infobox vcard']/tbody/tr")
        for line in infobox_table_lines:
            if len(_photo) == 0:
                flag_images = line.xpath(".//img")
                if len(flag_images) > 0:
                    _photo = [img.attrib['src'] for img in flag_images]
            th = line.xpath(".//th")
            td = line.xpath(".//td")
            if len(th) > 0:
                th_text_list = th[0].xpath(".//text()")
                th_text = self.filter_text_list(th_text_list)
                td_text = ""
                if len(td) > 0:
                    td_text_list = td[0].xpath(".//text()")
                    td_text = self.filter_text_list(td_text_list)
                _infobox_dict[th_text] = td_text
        return _photo, _infobox_dict

    def parse_toc(self, _selector):
        _toc = []
        toc_lines = _selector.xpath(
            "//div[@id='mw-content-text']/div[@class='mw-parser-output']/div[@id='toc']/ul//a")
        for toc_line in toc_lines:
            toc_line_text = toc_line.xpath("./span/text()")
            _trim_content = []
            for _ in toc_line_text:
                _ = _.replace("\n", "").strip()
                if '.mw-parser-output' not in _:
                    _trim_content.append(_)
            _toc.append(" ".join(_trim_content))
        return _toc

    def parse_contents(self, _selector):
        _contents = []
        content_lines = _selector.xpath("//div[@id='mw-content-text']/div[@class='mw-parser-output']/*")
        paragraph_content_list = []
        paragraph_tag = ''
        paragraph_header = ''
        paragraph_note = []
        paragraph_images = []
        paragraph_tables = []
        for content_line in content_lines:
            if content_line.tag in ['table']:
                if 'class' in content_line.attrib and content_line.attrib['class'] in ['wikitable', 'infobox']:
                    table_lines = content_line.xpath("./tbody/tr")
                    ths = []
                    table_contents = []
                    for line in table_lines:
                        if len(ths) == 0:
                            th_list = line.xpath("./th")
                            for th in th_list:
                                th_text_list = th.xpath(".//text()")
                                th_text = self.filter_text_list(th_text_list)
                                if len(th_text) > 0:
                                    ths.append(th_text)
                        else:
                            td_list = line.xpath("./td")
                            tds = []
                            for td in td_list:
                                td_text_list = td.xpath(".//text()")
                                td_text = self.filter_text_list(td_text_list)
                                tds.append(td_text)
                            if len(tds) == len(ths):
                                item = {}
                                for i in range(len(ths)):
                                    item[ths[i]] = tds[i]
                                table_contents.append(item)
                    paragraph_tables.append(table_contents)
            elif content_line.tag in ['div']:
                if 'class' in content_line.attrib and content_line.attrib['class'] == 'thumb tright':
                    images = content_line.xpath(".//img")
                    for image in images:
                        paragraph_images.append(image.attrib['src'])
                if 'role' in content_line.attrib and content_line.attrib['role'] == 'note':
                    note = content_line.xpath(".//text()")
                    note_text = self.filter_text_list(note)
                    paragraph_note.append(note_text)
            elif content_line.tag in ['p']:
                _content = content_line.xpath(".//text()")
                _content_text = self.filter_text_list(_content)
                paragraph_content_list.append(self.trim_ref(_content_text))
            elif content_line.tag in ['ul', 'ol']:
                li_list = content_line.xpath("./li")
                for li in li_list:
                    _content = li.xpath(".//text()")
                    _content_text = self.filter_text_list(_content)
                    if len(paragraph_content_list) == 0:
                        paragraph_content_list.append("\\n")
                    paragraph_content_list.append(self.trim_ref(_content_text))
            elif content_line.tag.startswith('h'):
                if paragraph_header == '':
                    paragraph_header = '总体情况'
                    paragraph_tag = 'h2'
                paragraph_text = '\\n        '.join(paragraph_content_list)
                content_item = {
                    'tag': paragraph_tag,
                    'header': paragraph_header
                }
                if len(paragraph_note) > 0:
                    content_item['note'] = paragraph_note
                if len(paragraph_text) > 0:
                    content_item['text'] = '        ' + paragraph_text
                if len(paragraph_images) > 0:
                    content_item['images'] = paragraph_images
                if len(paragraph_tables) > 0:
                    content_item['tables'] = paragraph_tables
                _contents.append(content_item)
                paragraph_content_list = []
                paragraph_images = []
                paragraph_tables = []
                paragraph_note = []
                _header = content_line.xpath(".//text()")[0]
                paragraph_header = self.trim_ref(_header)
                paragraph_tag = content_line.tag
        return _contents

    def parse_modified_time(self, _selector):
        _last_modified = _selector.xpath("//ul[@id='footer-info']/li[@id='footer-info-lastmod']")[0].text
        _last_modified = _last_modified[9:-1]
        m_date = _last_modified.split("(")[0].replace("年", "-").replace("月", "-").replace("日", "")
        m_time = _last_modified.split(")")[1].strip() + ':00'
        return m_date + m_time

    def filter_text_list(self, text_list):
        _trim_content = []
        for _ in text_list:
            _ = _.replace("\n", "")
            _ = _.replace('"', '\\"')
            _ = _.replace("\xa0", "")
            _ = _.replace("\ufeff", "")
            _ = self.trim_ref(_)
            _ = _.strip()
            if '.mw-parser-output' not in _:
                _trim_content.append(_)
        return trim_space(" ".join(_trim_content))
