from app import db

class Thread(db.Model):
    """Some thread, such as a topic, program, tutorial."""

    __tablename__ = 'thread'

    # Unique ID
    id = db.Column(db.Integer, primary_key=True)

    # Top comment
    top_comment_id = db.Column(db.Integer,
        db.ForeignKey('comment.id', use_alter=True))
    top_comment = db.relationship('Comment', foreign_keys=top_comment_id)

    # Post owning the thread, set only by Topic, Program, etc. In general, you
    # should use [owner_post] which groups them together.
    owner_topic = db.relationship('Topic')
    owner_program = db.relationship('Program')

    # Other fields populated automatically through relations:
    #  <comments>   The list of comments (of type Comment)

    COMMENTS_PER_PAGE = 20

    def __init__(self):
        """
        Create a empty Thread. Normally threads are not meant to be empty, so
        you should create a Comment with this thread as parent, then assign it
        as top comment with a call to set_top_comment().
        """
        self.top_comment_id = None

    def set_top_comment(self, top_comment):
        """
        Changes the top comment of the thread. The old top comment will usually
        become visible in the flow of posts instead of being pinned at the top.

        Arguments:
        top_comment -- new top comment, must belong to this thread
        """

        if top_comment not in self.comments:
            raise Exception("Cannot set foreign comment as top thread comment")

        self.top_comment = top_comment

    @property
    def owner_post(self):
        if self.owner_topic != []:
            return self.owner_topic[0]
        if self.owner_program != []:
            return self.owner_program[0]
        return None

    def is_default_accessible(self):
        if self.owner_program != []:
            return True
        if self.owner_topic != []:
            return self.owner_topic[0].forum.is_default_accessible()
        return False

    def delete(self):
        """Recursively delete thread and all associated contents."""
        # Remove reference to top comment
        self.top_comment = None
        db.session.add(self)
        db.session.commit()
        # Remove comments
        for c in self.comments:
            c.delete()
        # Remove thread
        db.session.commit()
        db.session.delete(self)

    def __repr__(self):
        return f'<Thread: #{self.id}>'
