import socket
import sys
import os
import subprocess
import time
import font
import random
voiced={}
aliasargs=[]
server = "irc.libera.chat"       #settings
chans = ["#main","#bread","##-bot-university","##"]
botnick = "breadbot"
loc="/opt/ircbot/"
names={}
tell={}
onjoin={}
rec=0
recfile=""
recname=""
rawpm=""
recd=[]
irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #defines the socket
print("connecting to:"+server)
irc.connect((server, 6667))                                                         #connects to the server
def saveconf():
 f=open(loc+server+"stats","w")
 totallines=""
 for x in names:
  line=x+" "+str(names[x])
  print(line)
  totallines=totallines+line+"\n"
 f.write(totallines)
 f.close()
def readconf():
 f=open(loc+server+"stats","r")
 lines=f.readlines()
 for x in lines:
  z=x.split(" ")
  names[z[0]]=int(z[1])
try:
 readconf()
except Exception as e:print(e)

def ircsend(msg):
 print("sending|",msg)
 irc.send(msg.encode('utf-8'))
def checkvoiced(chan):
 ircsend("WHO "+chan+"\n")
 print(chan)
 breaked=1
 try:
  print(voiced[chan][0])
 except:
  print("")
  voiced[chan]=[]
 while breaked<5:
  raw=irc.recv(4040).decode("utf-8", errors='ignore')  #receive the tex
  breaked=breaked+1
  if raw.replace("End of /WHO list.","").replace("End of /MOTD","")!=raw:breaked=99
  raw=raw.split("\n")
  for z in raw:
   if z.find('PING') != -1:                          #check if 'PING' is found
      ircsend('PONG ' + z.split() [1] + '\r\n') #returnes 'PONG' back to the server (prevents pinging out!
      saveconf()
   text=z.split(" ")
   print("_".join(text),"text leng",len(text))
   if len(text)>=9:
    if (not (text[7].replace("~","") in voiced[chan])) and (text[8])[1:99] in ["~","@","+"]:
     voiced[chan].append(text[7].replace("~",""))
     print("ADDED TO FUCKING VOICED")
    if ((text[7].replace("~","") in voiced[chan])) and (not (text[8])[1:99] in ["~","@","+"]):
       voiced[chan].pop(voiced[chan].index(text[7].replace("~","")))
       print(text[7],"was removed")
    print(z,"parsed",text[7],text[8])
ircsend("USER "+ botnick +" "+ botnick +" "+ botnick +" :This is a fun bot!\n") #user authentication
ircsend("NICK "+ botnick +"\n")                            #sets nick
ircsend("PRIVMSG nickserv :iNOOPE\r\n")   #auth
x=0
while x<2:
 text=irc.recv(4040).decode("utf-8", errors='ignore')
 x=x+1
 if text.replace("End of /MOTD command.","")!=text:break
 print(text)
for x in chans:
 ircsend("JOIN "+ x +"\n")
 checkvoiced(x)
while 1:    #puts it in a loop
  raw=irc.recv(2040).decode("utf-8", errors='ignore')  #receive the text
  raw=raw.split("\n")
  for text in raw:
   if rawpm!="":
    ircsend("PRIVMSG "+rawpm+" :"+text)
    rawpm=""
   name="NoName"
   if text.find("MODE #")!=-1:
    try:
     checkvoiced(text.split("MODE")[1].split(" ")[0])
    except:print("corrupt headers")
    print("voice updated")
   if text.find("!")!=-1 and text[0]==":":
     name=text[1:text.find("!")]
     print("name",name)
     if name in names:
      names[name]+=1
     else:names[name]=0
   print(text)   #print text to console
   if text.find("End of /MOTD command.")!=-1 or text.find(":You have not registered")!=-1:
      for x in chans:ircsend("JOIN "+ x +"\n")
   if text.find("PRIVMSG #")!=-1: #handle commands
      command=text[text.find("PRIVMSG"):999]
      chan=command[command.find("#"):999]
      chan=chan[0:chan.find(":")-1].strip()
      print("|"+chan+"|")
      command=command[command.find(":")+1:999]
      print("cmd",command)
      out=""
      longout=[]
      uservoice=1
      if chan=="##" and (not (name in voiced[chan])):uservoice=0
      if (command.strip().split(" ")[0]==":stop" and recfile!="") or rec==1:
       rec=0
       with open(loc+"ascii/"+recfile,"w") as f:
         f.write("\n".join(recd))
       recd=[]
       recname=""
      if rec!=0 and name==recname:
        rec-=1
        print("write",command)
        recd.append(command)
      if name in tell:
        out=tell[name]
        tell.pop(name)
      if "~"+name in tell:
         ircsend("PRIVMSG "+name+" :"+tell["~"+name]+"\n")
         tell.pop("~"+name)
      if name in onjoin:
        ircsend("PRIVMSG "+onjoin[name]+" :"+name+" is online\n")
        onjoin.pop(name)
      if command[0]==":" and name!=recname and uservoice==1: #check for command char
       cmd=command[1:9999].strip().split(" ")
       print("true cmd:"+cmd[0]+".")
       if os.path.isfile(loc+"ascii/"+cmd[0]) and (not (cmd[0][0]=="/" or cmd[0][0]==".")):
         text_file = open(loc+"ascii/"+cmd[0], "r")
         longout = text_file.readlines()
         text_file.close()
         if len(longout)==1:
          temp=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()).split(" ")
          longout[0]=longout[0].replace("$DATE",temp[0])
          longout[0]=longout[0].replace("$TIME",temp[1])
          if len(cmd)>=2:
            longout[0]=longout[0].replace("$1",cmd[1])
            longout[0]=longout[0].replace("$*"," ".join(cmd[1:999]))
          if len(cmd)>=3:longout[0]=longout[0].replace("$2",cmd[2])
       if cmd[0]=="startrec" and len(cmd)==2 and (not (cmd[1][0]=="/" or cmd[1][0]==".") and cmd[1].replace("/","")==cmd[1]) and uservoice==1:
        if cmd[1]!="help" and len(cmd[1])>=2:
         rec=20
         recfile=cmd[1]
         out="recording started no longer then 10 lines of art,also $1 is replaced with user input"
         recname=name
        else:out="no"
       if cmd[0]=="tell" and len(cmd)>=3:
         tell[cmd[1]]=name+">"+" ".join(cmd[2:999])
       if cmd[0]=="voiced" and uservoice==1 and len(cmd)==2:
        try:
         out=" ".join(voiced[cmd[1]])
        except:out="chan not added yet"
        checkvoiced(cmd[1])
       if cmd[0]=="voice" and len(cmd)==2:
        checkvoiced(chan)
        out="no"
        if cmd[1] in voiced[chan]:out="yes"
       if cmd[0]=="font" and len(cmd)!=1 and uservoice==1:
         try:
          longout=font.gen(" ".join(cmd[1:999]))
         except Exception as e:
          out='ERROR standard ascii only pls'
       if cmd[0]=="list":
        out=" ".join(os.listdir(loc+"ascii"))
       if cmd[0]=="onjoin" and len(cmd)==2:
         onjoin[cmd[1]]=name
         out="OK"
       if cmd[0]=="users" and uservoice==1:
        out=",".join(names)
       if cmd[0]=="stat" and len(cmd)==2:
        try:
         out=cmd[1]+" sent "+str(names[cmd[1]])+"msgs"
         print(name,names[cmd[1]])
        except:out="name not found"
       if cmd[0]=="rand" and len(cmd)==3:
        try:
         out=str(random.randint(int(cmd[1]),int(cmd[2])))
        except:out=":rand <int> <int>,no letters >:("
       if cmd[0]=="chan":out=chan
       if cmd[0]=="uptime":
        out=subprocess.check_output('uptime').decode("utf8")
       if cmd[0]=="echo" and len(cmd)!=1:out=" ".join(cmd[1:999])
      if out!="":ircsend("PRIVMSG "+chan+" :"+ out+"\n")
      if longout!=[]:
       y=0
       for x in longout:
        y+=1
        ircsend("PRIVMSG "+chan+" :"+x+"\n")
        if y>3:time.sleep(0.1)
        if y>5:time.sleep(0.25)
        if y>10:time.sleep(0.1)
        if y>15:
         y=0
         break
   if text.find("PRIVMSG "+botnick+" :") !=-1: #allow for direct control of bot
     ircsend(text.split("PRIVMSG "+botnick+" :")[1]+"\n")        #join the chan
     print(text)
   if text.find('PING') != -1:                          #check if 'PING' is found
      ircsend('PONG ' + text.split() [1] + '\r\n') #returnes 'PONG' back to the server (prevents pinging out!
      saveconf()
