import json
from giara.confManager import ConfManager
from giara.singleton import Singleton
from time import time


class Expirations:  # in days
    subreddit = 60 * 60 * 24 * 7
    user = 60 * 60 * 24 * 14


class NetCache(metaclass=Singleton):

    BASE_SCHEMA = {
        'subreddits': {},
        'users': {}
    }

    def __init__(self):
        self.confman = ConfManager()
        self.cache = self.BASE_SCHEMA
        self.dir = self.confman.network_cache_path
        self.index_path = self.dir.joinpath(
            'cache_index.json'
        )
        if not self.index_path.is_file():
            self.save()
        else:
            try:
                with open(self.index_path, 'r') as fd:
                    self.cache = json.loads(fd.read())
            except Exception:
                self.save()

    def save(self):
        with open(self.index_path, 'w') as fd:
            fd.write(json.dumps(self.cache))

    def invalidate_subreddit(self, subreddit_id):
        self.cache['subreddits'].pop(subreddit_id)
        self.save()

    def cache_subreddit(self, subreddit, subreddit_id):
        res = {
            'timestamp': time(),
            'id': subreddit.id,
            'title': subreddit.title,
            'display_name': subreddit.display_name,
            'display_name_prefixed': subreddit.display_name_prefixed,
            'icon_img': subreddit.icon_img,
            'community_icon': subreddit.community_icon,
            'subscribers': subreddit.subscribers,
            'created_utc': subreddit.created_utc,
            'user_is_subscriber': subreddit.user_is_subscriber,
            'description': subreddit.description
        }
        self.cache['subreddits'][subreddit_id] = res
        self.save()
        return res

    def get_subreddit(self, subreddit, subreddit_id):
        if subreddit_id in self.cache['subreddits'].keys():
            res = self.cache['subreddits'][subreddit_id]
            if time() - res['timestamp'] <= Expirations.subreddit:
                return res
        return self.cache_subreddit(subreddit, subreddit_id)


netcache = NetCache()


class CachedSubreddit:
    def __init__(self, subreddit, subreddit_id):
        self.subreddit = subreddit
        self.subreddit_id = subreddit_id
        self.cached = netcache.get_subreddit(self.subreddit, self.subreddit_id)

    def _fetch_wrapper(self):
        netcache.invalidate_subreddit(self.subreddit_id)
        self.subreddit._fetch()
        self.cached = netcache.get_subreddit(self.subreddit, self.subreddit_id)

    def __getattr__(self, name):
        if name == '_fetch':
            return self._fetch_wrapper
        if name in self.cached.keys():
            return self.cached[name]
        else:
            print(f'Falling back to praw subreddit for field {name}')
            return getattr(self.subreddit, name)
