#!/usr/bin/env python3

import os
import sys
import yaml
import dateutil
import feedparser

from mastodon import Mastodon
from datetime import datetime, timezone

def main():
    config_file = get_config_file()
    if not os.path.isfile(config_file):
        setup(config_file)        

    config = read_config(config_file)

    masto = Mastodon(
        api_base_url=config['url'],
        client_id=config['client_id'],
        client_secret=config['client_secret'],
        access_token=config['access_token']
    )

    for feed in config['feeds']:
        for entry in get_feed(feed['url'], config['updated']):
            print(feed['template'].format(**entry))
            #masto.status_post(get_text(entry))

    save_config(config, config_file)

def get_config_file():
    if __name__ == "__main__" and len(sys.argv) > 1:
        config_file = sys.argv[1]
    else:
        config_file = os.path.join(os.path.expanduser("~"), ".feediverse")
    return config_file

def save_config(config, config_file):
    copy = dict(config)
    copy['updated'] = datetime.now(tz=timezone.utc).isoformat()
    with open(config_file, 'w') as fh:
        fh.write(yaml.dump(copy, default_flow_style=False))

def read_config(config_file):
    config = {}
    with open(config_file) as fh:
        config = yaml.load(fh)
        if 'updated' in config:
            config['updated'] = dateutil.parser.parse(config['updated'])
        else:
            config['updated'] = datetime.now(tz=timezone.utc)
    return config

def get_feed(feed_url, last_update):
    new_entries = 0
    feed = feedparser.parse(feed_url)
    for entry in feed.entries:
        e = get_entry(entry)
        if last_update is None or e['updated'] > last_update:
            new_entries += 1
            yield e
    return new_entries

def get_entry(entry):
    hashtags = []
    for tag in entry.get('tags', []):
        hashtags.add('#{}'.format(tag.value))
    return {
        'url': entry.id,
        'title': entry.title,
        'summary': entry.get('summary', ''),
        'hashtags': ' '.join(hashtags),
        'updated': dateutil.parser.parse(entry['updated']),
    }

def setup(config_file):
    url = input('What is your Mastodon Instance URL? ')
    have_app = input('Do you have your app credentials already? [y/n] ')
    if have_app.lower() == 'y':
        name = 'feediverse'
        client_id = input('What is your app\'s client id: ')
        client_secret = input('What is your client secret: ')
        access_token = input('access_token: ')
    else:
        print("Ok, I'll need a few things in order to get your access token")
        name = input('app name (e.g. feediverse): ') 
        client_id, client_secret = Mastodon.create_app(name, scopes=['read', 'write'], website='https://github.com/edsu/feediverse')
        username = input('mastodon username (email): ')
        password = input('mastodon password (not stored): ')
        access_token = m.log_in(username, password)

    m = Mastodon(client_id, client_secret)
    feed_url = input('RSS/Atom feed URL to watch: ')
    config = {
        'name': name,
        'url': url,
        'client_id': client_id,
        'client_secret': client_secret,
        'access_token': access_token,
        'feeds': [
            {'url': feed_url, 'template': '{title} {url}'}
        ]
    }
    save_config(config, config_file)
    print("Your feediverse configuration has been saved to {}".format(config_file))
    print("Add a line line this to your crontab to check every 15 minutes:")
    print("*/15 * * * * /usr/local/bin/feediverse")

if __name__ == "__main__":
    main()
