#####################################################################
#                                                                   #
#  THIS IS A SOURCE CODE FILE FROM A PROGRAM TO INTERACT WITH THE   #
# LBRY PROTOCOL ( lbry.com ). IT WILL USE THE LBRY SDK ( lbrynet )  #
# FROM THEIR REPOSITORY ( https://github.com/lbryio/lbry-sdk )      #
# WHICH I GONNA PRESENT TO YOU AS A BINARY. SINCE I DID NOT DEVELOP #
# IT AND I'M LAZY TO INTEGRATE IN A MORE SMART WAY. THE SOURCE CODE #
# OF THE SDK IS AVAILABLE IN THE REPOSITORY MENTIONED ABOVE.        #
#                                                                   #
#      ALL THE CODE IN THIS REPOSITORY INCLUDING THIS FILE IS       #
# (C) J.Y.Amihud and Other Contributors 2021. EXCEPT THE LBRY SDK.  #
# YOU CAN USE THIS FILE AND ANY OTHER FILE IN THIS REPOSITORY UNDER #
# THE TERMS OF GNU GENERAL PUBLIC LICENSE VERSION 3 OR ANY LATER    #
# VERSION. TO FIND THE FULL TEXT OF THE LICENSE GO TO THE GNU.ORG   #
# WEBSITE AT ( https://www.gnu.org/licenses/gpl-3.0.html ).         #
#                                                                   #
# THE LBRY SDK IS UNFORTUNATELY UNDER THE MIT LICENSE. IF YOU ARE   #
# NOT INTENDING TO USE MY CODE AND JUST THE SDK. YOU CAN FIND IT ON #
# THEIR OFFICIAL REPOSITORY ABOVE. THEIR LICENSE CHOICE DOES NOT    #
# SPREAD ONTO THIS PROJECT. DON'T GET A FALSE ASSUMPTION THAT SINCE #
# THEY USE A PUSH-OVER LICENSE, I GONNA DO THE SAME. I'M NOT.       #
#                                                                   #
# THE LICENSE CHOSEN FOR THIS PROJECT WILL PROTECT THE 4 ESSENTIAL  #
# FREEDOMS OF THE USER FURTHER, BY NOT ALLOWING ANY WHO TO CHANGE   #
# THE LICENSE AT WILL. SO NO PROPRIETARY SOFTWARE DEVELOPER COULD   #
# TAKE THIS CODE AND MAKE THEIR USER-SUBJUGATING SOFTWARE FROM IT.  #
#                                                                   #
#####################################################################

# This file will fetch an LBRY URL directly and print out various
# options that the user may do with the publication.

from subprocess import *
import json
import os
from flbry.variables import *
from flbry import markdown
from flbry import channel
from flbry import search
from flbry import comments

def get(url=""):
    
    # The user might type the word url and nothing else.
    
    if not url:
        url = input(" LBRY url :: ")
        
    # Then let's fetch the url from our beloved SDK.

    out = check_output(["flbry/lbrynet",
                         "resolve", url])

    # Now we want to parse the json

    try:
        out = json.loads(out)
    except:
        print("   Connect to LBRY first.")
        return

    out = out[url]

    #### FORCE SEARCH ###

    # Sometimes user might type something that is not a url
    # in this case ["value_type"] will not be loaded. And in
    # this case we can load search instead.

    if "value_type" not in out:
        search.simple(url)
        return

    # Now that we know that don't search for it. We can make
    # one thing less broken. Sometimes a user might type a
    # urls that's going to be resolved but that doesn't have
    # the lbry:// in the beginning of it. Like typing
    # @blenderdumbass instead of lbry://blenderdumbass

    # I want to add the lbry:// to it anyway. So non of the
    # stuff later will break.

    if not url.startswith("lbry://") and not url.startswith("@"):
        url = "lbry://" + url
    
    # Now let's print some useful information

    ##### NAME URL INFORMATION #####
    
    center("Publication Information")
    d = {"categories":["lbry url", "title"],
         "size":[1,1],
         "data":[[url]]}
    try:    
        # This prints out the title
        d["data"][0].append(out["value"]["title"])
    except:
        d["data"][0] = [url]
        d["data"][0].append("[no title]")

    table(d, False)

    #### LICENSE ####

    try:
        
        d = {"categories":["License"],
         "size":[1],
         "data":[[out["value"]["license"]]]}
    except:
        d = {"categories":["License"],
         "size":[1],
         "data":[["[failed to load license]"]]}
    table(d, False)
    
    #### TAGS #####

    d = {"categories":[],
         "size":[],
         "data":[[]]}
    try:
        for tag in out["value"]["tags"]:
                    d["categories"].append(" ")
                    d["size"].append(1)
                    d["data"][0].append(tag)
    except:
        d = {"categories":[" "],
         "size":[1],
         "data":[["[no tags found]"]]}
    
    table(d, False)

    #### FILE INFO #####

    d = {"categories":["Value Type", "File Type", "File Size", "Duration"],
         "size":[1,1,1, 1],
         "data":[[]]}
    try:
         d["data"][0].append(what[out["value_type"]])
    except:
         d["data"][0].append("[no value type]")
    try:
         d["data"][0].append(out["value"]["source"]["media_type"])
    except:
         d["data"][0].append("[no file type]")
    try:
         d["data"][0].append(csize(out["value"]["source"]["size"]))
    except:
         d["data"][0].append("[no file size]")
    try:
         d["data"][0].append(timestring(float(out["value"]["video"]["duration"])))
    except:
         d["data"][0].append("[no duration]")

         
    table(d, False)

    ##### CHANNEL INFORMATION ####

    center("Channel Information")
    d = {"categories":["lbry url", "title"],
         "size":[1,1],
         "data":[[]]}

    try:    
        # This prints out the title
        d["data"][0].append(out["signing_channel"]["name"])
        d["data"][0].append(out["signing_channel"]["value"]["title"])
    except:
        d["data"][0] = []
        d["data"][0].append("[no url]")
        d["data"][0].append("[anonymous publisher]")

    table(d, False)


    #### LBC INFORMATION ####

    center("LBRY Coin ( LBC ) Information")
    d = {"categories":["combined", "at upload", "support"],
         "size":[1,1,1],
         "data":[[]]}

    try:
        fullamount = float(out["amount"]) + float(out["meta"]["support_amount"])
        # This prints out the title
        d["data"][0].append(fullamount)
        d["data"][0].append(out["amount"])
        d["data"][0].append(out["meta"]["support_amount"])
        
    except:
        d["data"][0] = []
        d["data"][0].append("[no data]")
        d["data"][0].append("[no data]")
        d["data"][0].append("[no data]")

    table(d, False)

    #### PRICE ####
    
    try:
        # Print the prince of this publication in LBC
        center("PRICE: "+out["value"]["fee"]["amount"]+" "+out["value"]["fee"]["currency"], "bdrd", blink=True)

    except:
        pass
    
    ### REPOST ####

    # Sometimes a user wants to select a repost. This will not
    # load anything of a value. A repost is an empty blob that
    # links to another blob. So I want to automatically load
    # the actuall publication it self here.

    if out["value_type"] == "repost":
        get(out["reposted_claim"]["canonical_url"])
        return

    
    
    # Some things are too big to output like this in the terminal
    # so for them I want the user to type a command.

    center("--- for publication commands list type help --- ")

    # So we are going to start a new while loop here. IK crazy.
    # this one will handle all the commands associated with the
    # currently selected publication.
    
    while True:
        c =  input(typing_dots())

        if not c:
            break

        elif c == "help":
            markdown.draw("help/url.md", "Publication Help")
            
        elif c == "https":
            Popen(['xdg-open',
                   url.replace("lbry://", "https://spee.ch/").replace("#", ":").replace("(", "%28").replace(")", "%29")], 
                              stdout=DEVNULL,
                              stderr=STDOUT)
        elif c == "odysee":
            Popen(['xdg-open',
                   url.replace("lbry://", "https://odysee.com/").replace("#", ":").replace("(", "%28").replace(")", "%29")], 
                              stdout=DEVNULL,
                              stderr=STDOUT)
        elif c.startswith("open"):

            # Selecting the software command in a smart way
            if len(c) < 6:
                p = input(" Open in : ")
            else:
                p = c[5:]

            Popen([p,
                   url.replace("lbry://", "https://spee.ch/").replace("#", ":").replace("(", "%28").replace(")", "%29")], 
                              stdout=DEVNULL,
                              stderr=STDOUT)
            
        elif c == "description":
            
            #print(out["value"]["description"])

            # Here I want to print out the description of the publication.
            # but since, they are most likely in the markdown format I
            # need to implement a simple markdown parser. Oh wait.... I
            # have one. For the article read function. How about using it
            # here?

            # First we need to save the description into a file. Let's use
            # /tmp/ since there files are automatically cleaned up by the
            # system.

            try:
                savedes = open("/tmp/fastlbrylastdescription.md", "w")
                savedes.write(out["value"]["description"])
                savedes.close()
            except:
                savedes = open("/tmp/fastlbrylastdescription.md", "w")
                savedes.write("This file has no description.")
                savedes.close()

            # Now let's just simply load the markdown on this file.
            markdown.draw("/tmp/fastlbrylastdescription.md", "Description")
            

        elif c == "play":

            # Then we want to tell the SDK to start downloading.
            playout = check_output(["flbry/lbrynet",
                                    "get", url])
            # Parsing the Json
            playout = json.loads(playout)
            
            # Then we want to launch the player
            Popen(["xdg-open",
                   playout['download_path']],
                              stdout=DEVNULL,
                              stderr=STDOUT)
        elif c == "save":

            # Then we want to tell the SDK to start downloading.
            playout = check_output(["flbry/lbrynet",
                                    "get", url])
            # Parsing the Json
            playout = json.loads(playout)
            
            print("    Saved to :", playout['download_path'])

        elif c == "read":
            # Then we want to tell the SDK to start downloading.
            playout = check_output(["flbry/lbrynet",
                                    "get", url])
            # Parsing the Json
            playout = json.loads(playout)

            # Present the article to the user.
            markdown.draw(playout['download_path'], out["value"]["title"])

        elif c == "channel":

            # This a weird one. If the publication is a channel we
            # want it to list the publications by that channel.
            # If a publication is a publication. We want it to list
            # publications by the channel that made the publication.

            if out["value_type"] == "channel":
                channel.simple(url)
            else:
                channel.simple(out["signing_channel"]["canonical_url"].replace("lbry://",""))

        elif c == "comments":
            comments.list(out["claim_id"], url)

        elif c.startswith("reply"):
            c = c + ' '
            comments.post(out["claim_id"], c[c.find(" "):])
