#!/bin/env python
"""
Syndicate Medium Posts

Following the API documentation:
https://github.com/Medium/medium-api-docs/tree/69c4cdb894e74ac7710572f9a34bc2421a8def2e

"""
import json
import subprocess
import time

from http.client import HTTPSConnection
from urllib.parse import urlparse

import frontmatter

AUTHOR_ID = "18bad95d2020608a45ef502ef0db83d2cad2e28886d8d3eeef71a6bd089fc2a4e"

def syndicate_post(post):
    """
    Takes a blog post and syndicates it to Medium
    """
    # Grab secret
    medium_secret = ""
    with open("secrets/medium.secret", "r") as secret_file:
        medium_secret = secret_file.read().strip()

    # Structure API Request
    blog_post = dict(
        title=post['title'],
        contentFormat="html",
        content=post['content_html'],
        tags=post['tags'],
        canonicalUrl=post['url'],
        publishStatus="public",
        license="all-rights-reserved",
        notifyFollowers=False # TODO: Temporary while refreshing content
    )
    request_headers = {
            "Host": "api.medium.com",
            "Authorization": f"Bearer {medium_secret}",
            "Content-Type": "application/json",
            "Accept": "application/json",
            "Accept-Charset": "utf-8",
    }

    # Send Request
    conn = HTTPSConnection("api.medium.com")
    conn.request(
        "POST",
        f"/v1/users/{AUTHOR_ID}/posts",
        json.dumps(blog_post).encode("utf-8"),
        request_headers
    )

    # Check and parse response
    response = conn.getresponse()
    if response.status != 201:
        raise Exception(f"Medium API rejected the request with response code {response.status}")
    medium_response = json.loads(response.read().decode('utf-8'))
    conn.close()

    return medium_response

def update_front_matter(post, medium_data):
    """
    Take the medium response object and encode
    the unique identifier back to the blog post.
    """
    # Figure out path of file
    ORIG_URL = urlparse(post['id'])
    file_path = "content" + ORIG_URL.path[:-1] + ".md"

    # Read existing frontmatter and edit the post id
    item = {}
    with open(file_path, "r", encoding="UTF-8") as content_file:
        item = frontmatter.load(content_file)
        item['medium_post_id'] = medium_data['data']['id']
    
    # Write out new frontmatter
    with open(file_path, "w", encoding="UTF-8") as content_file:
        content_file.write(frontmatter.dumps(item))
        
if __name__ == "__main__":
    # Generate the necessary feed files
    subprocess.run(['hugo'], check=True)

    # Grab blog's feed
    data = ""
    with open("public/blog/index.json", "r", encoding="UTF-8") as feed_file:
        data = feed_file.read()
    feed_data = json.loads(data)

    # Go through each post and check syndication status
    for post in feed_data['items']:
        medium_enabled = post['_syndication']['medium']['enabled']
        medium_post_id = post['_syndication']['medium']['post_id']
        if medium_enabled and medium_post_id is None:
            # Syndicate.....
            print(f"Syndicating \"{post['title']}\"")
            medium_result = syndicate_post(post)
            update_front_matter(post, medium_result)
            print(medium_result['data']['url'])
            time.sleep(60)