#!/usr/bin/env python
# vim:fileencoding=utf-8
"""
https://apnews.com
"""

from datetime import datetime, timezone

from calibre.web.feeds.news import BasicNewsRecipe, classes


class AssociatedPress(BasicNewsRecipe):
    title = 'Associated Press'
    description = (
        'Read the latest headlines, breaking news, and videos at APNews.com, the definitive '
        'source for independent journalism from every corner of the globe. Articles from Front Page.'
    )
    __author__ = 'unkn0wn'
    language = 'en'
    encoding = 'utf-8'
    no_stylesheets = True
    remove_javascript = True
    ignore_duplicate_articles = {'url'}
    remove_empty_feeds = False
    remove_attributes = ['style', 'height', 'width']
    simultaneous_downloads = 1
    oldest_article = 1  # days; AP publishes constantly
    cover_url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/0c/Associated_Press_logo_2012.svg/662px-Associated_Press_logo_2012.svg.png'

    keep_only_tags = [
        classes('StoryPage-lede-content Page-lead Page-byline-info RichTextStoryBody'),
    ]
    remove_tags = [
        classes('displayNone Advertisement HTMLModuleEnhancement AudioEnhancement'),
        dict(
            name=[
                'source',
                'button',
                'svg',
                'template',
                'video',
                'astro-island',
                'iframe',
                'document',
            ]
        ),
        dict(attrs={'data-parsely-title': 'Related Stories'}),
    ]

    extra_css = '''
        .Page-byline-info, .Page-breadcrumbs, .CarouselSlide-info, .Figure-caption { font-size:small; }
        img {display:block; margin:0 auto;}
        em { color: #202020; }
    '''

    def parse_index(self):
        feeds = []
        soup = self.index_to_soup('https://apnews.com')
        for a in soup.findAll(
            'a',
            attrs={'href': lambda x: x and x.startswith('https://apnews.com/article/')},
        ):
            url = a['href']
            title = self.tag_to_string(a)
            pub = self._fetch_published_time(url)
            if pub is None:
                self.log.warn('Skipping (no published_time):', url)
                continue
            self.log(title, '\n\t', url, '\n\t', pub.isoformat())
            feeds.append({
                'title': title,
                'url': url,
                'date': pub.strftime('%Y-%m-%d %H:%M:%S'),
                'timestamp': pub.timestamp(),
            })
        return [('Articles', feeds)]

    def _fetch_published_time(self, url):
        # AP has no RSS feeds, so parse_index can't filter by date without
        # fetching each candidate article. Read <meta property="article:
        # published_time"> from the article HTML so oldest_article applies.
        cache = getattr(self, '_pub_time_cache', None)
        if cache is None:
            cache = self._pub_time_cache = {}
        if url in cache:
            return cache[url]
        try:
            soup = self.index_to_soup(url)
        except Exception as e:
            self.log.warn('AP published_time fetch failed for', url, ':', e)
            cache[url] = None
            return None
        meta = soup.find('meta', attrs={'property': 'article:published_time'})
        if not meta or not meta.get('content'):
            cache[url] = None
            return None
        try:
            pub = datetime.fromisoformat(meta['content'])
        except Exception as e:
            self.log.warn('AP bad published_time on', url, ':', e)
            cache[url] = None
            return None
        if pub.tzinfo is None:
            pub = pub.replace(tzinfo=timezone.utc)
        cache[url] = pub
        return pub

    def preprocess_html(self, soup):
        for v in soup.findAll('bsp-jw-player', attrs={'poster': True}):
            v.name = 'img'
            v.attrs = {'src': v.get('poster', '')}
        for st in soup.findAll(**classes('CarouselSlide-infoDescription Figure-caption')):
            if p := st.find('p'):
                p.name = 'span'
        for h in soup.findAll(['h2', 'h3']):
            h.name = 'h4'
        for img in soup.findAll('img', attrs={'srcset': True}):
            img['src'] = img['srcset'].split()[0]
        for img_ in soup.findAll('img', attrs={'data-flickity-lazyload-srcset': True, 'srcset': False}):
            img_['src'] = img_['data-flickity-lazyload-srcset'].split()[0]
        return soup
