#!/usr/bin/env python3
"""
A one line cli replacement
"""

import os
import re
import subprocess
import sys
import tkinter
from urllib.parse import quote_plus


historyfile = os.path.join(os.environ["HOME"],".olc_history")
#browser = os.environ.get("BROWSER", "iceweasel -new-window")
browser = os.environ.get("BROWSER", "brauser")


def openURL(url):
	url = url.replace("twitter.com", "nitter.net")
	subprocess.Popen(browser.split()+[url])


class OneLineCli(tkinter.Frame):

	def __init__(self,parent):
		tkinter.Frame.__init__(self,parent)
		sel = self._getSelection()
		self.commandEntry = tkinter.Entry(self, width=60)
		self.commandEntry.insert(0, sel)
		self.commandEntry.selection_range(0, tkinter.END)
		self.commandEntry.bind("<Return>",lambda a, self=self:self.quit())
		self.commandEntry.bind("<Escape>",self.invalidate)
		self.commandEntry.bind("<Up>",self.historyUp)
		self.commandEntry.bind("<Down>",self.historyDown)
		self.commandEntry.bind("<Tab>",self.historyTab)
		self.commandEntry.focus()
		self.commandEntry.pack()
		self.loadHistory()

	def _getSelection(self):
		try:
			return self.selection_get()
		except:
			return ""

	def loadHistory(self):
		try:
			with open(historyfile, "r", encoding="utf-8") as f:
				self.history = f.read().split("\n")
		except IOError:
			self.history = []
		self.histpointer = len(self.history)

	def saveHistory(self):
		command = self.getCommand()
		if command and self.history and command!=self.history[-1]:
			self.history.append(command)
		if len(self.history)>100:
			del self.history[0]
		with open(historyfile, "w", encoding="utf-8") as f:
			f.write("\n".join(self.history))

	def historyUp(self,event):
		if self.histpointer>0:
			self.histpointer -= 1
			self.commandEntry.delete(0, tkinter.END)
			self.commandEntry.insert(0, self.history[self.histpointer])

	def historyDown(self,event):
		if self.histpointer<len(self.history):
			self.histpointer += 1
			self.commandEntry.delete(0,tkinter.END)
			try:
				self.commandEntry.insert(0, self.history[self.histpointer])
			except IndexError:
				pass
	
	def historyTab(self,event):
		self.commandEntry.delete(tkinter.INSERT,tkinter.END)
		command = self.getCommand()
		for i in range(self.histpointer-1,0,-1):
			if self.history[i].startswith(command):
				self.histpointer = i
				self.commandEntry.insert(tkinter.INSERT,
					self.history[self.histpointer][len(command):])
				self.commandEntry.select_range(len(command),tkinter.END)
				self.commandEntry.icursor(len(command))
				break
		return "break"

	def getCommand(self):
		s = re.sub(r"\s*\n\s*", "", self.commandEntry.get().strip())
		return s
	
	def invalidate(self,event):
		self.commandEntry.delete(0,tkinter.END)
		self.quit()


def handle_ads(command):
	if re.match(r"\d\d\d\d", command):
		openURL("http://adsabs.harvard.edu/cgi-bin/nph-abs_connect?db_key=ALL"
			"&PRE=YES&warnings=YES&bibcode=%s"%quote_plus(command))
		return 1
	return 0

def handle_google(command):
	if command.startswith("google:"):
		openURL("http://www.google.com/search?tbs=li:1&q=%s"%(
			quote_plus(command[7:])))
		return 1
	return 0

def handle_duck(command):
	if command.startswith("duck:"):
		openURL("https://duckduckgo.com/html?q=%s"%
			quote_plus(command[5:]))
		return 1
	return 0

def handle_fb(command):
	if command.startswith("fb:"):
		openURL("https://fireball.de/de/search?q=%s"%
			quote_plus(command[3:]))
		return 1
	return 0

def handle_osm(command):
	if command.startswith("osm:"):
		openURL("http://www.openstreetmap.org/?query=%s"%
			quote_plus(command[4:]))
		return 1
	return 0

def handle_q(command):
	if command.startswith("q:"):
		openURL("https://metager.de/meta/meta.ger3?focus=web&eingabe=%s"%
			quote_plus(command[2:]))
		return 1
	return 0

def handle_python(command):
	if command.startswith("python:"):
		openURL("http://docs/python/library/%s.html"%(command[7:]))
		return 1
	return 0

def handle_py3(command):
	if command.startswith("py3:"):
		openURL("http://docs/python3-doc/html/library/%s.html"%(
			command[4:]))
		return 1
	return 0

def handle_wp(command):
	if command.startswith("wp:"):
		openURL("http://en.wikipedia.org/w/index.php?search=%s"%(
			quote_plus(command[3:])))
		return 1
	return 0

def handle_wpd(command):
	if command.startswith("wpd:"):
		openURL("http://de.wikipedia.org/w/index.php?search=%s"%(
			quote_plus(command[4:])))
		return 1
	return 0

def handle_wpl(command):
	if command.startswith("wpl:"):
		openURL("http://localhost:8780/pages/%s"%(
			quote_plus(command[4:])))
		return 1
	return 0

def handle_mdn(command):
	if command.startswith("mdn:"):
		openURL("https://developer.mozilla.org/en-US/search?q=%s"%
			quote_plus(command[4:]))
		return 1
	return 0

def handle_man(command):
	if command.startswith("man:"):
		os.system("env LC_ALL=C tkman %s"%command[4:])
		return 1
	return 0

def handle_url(command):
	if command.startswith("ftp://"):
		openURL(command)
		return 1
	elif command.startswith("http://"):
		openURL(command)
		return 1
	elif command.startswith("https://"):
		openURL(command)
		return 1
	elif command.startswith("www."):
		openURL("http://%s"%(command))
		return 1
	else:
		return 0

def handle_wayback(command):
	if command.startswith("wayback:"):
		openURL("http://web.archive.org/web/*/%s"%(
			command[8:]))
		return 1
	return 0

def handle_debbug(command):
	if command.startswith("#"):
		openURL("https://bugs.debian.org/%s"%command[1:])
		return 1
	return 0

def handle_deb(command):
	if command.startswith("deb:"):
		openURL("https://packages.debian.org/search?keywords=%s"%quote_plus(command[4:]))
		return 1
	return 0


def handle_css(command):
	if command.startswith("css:"):
		openURL("https://developer.mozilla.org/en-US/docs/Web/CSS/"
			+command[4:])
		return 1
	return 0

def handle_js(command):
	if command.startswith("js:"):
		openURL("https://developer.mozilla.org/en-US/docs/Web/API/"
			+command[3:])
		return 1
	return 0

def handle_html(command):
	if command.startswith("html:"):
		openURL("https://developer.mozilla.org/en-US/docs/Web/HTML/Element/"
			+command[5:])
		return 1
	return 0

def handle_pypi(command):
	if command.startswith("pypi:"):
		openURL("https://pypi.org/search/?q="
			+quote_plus(command[5:]))
		return 1
	return 0

def handle_btds(command):
	mat = re.match(r"(\d\d)/(\d+)$", command)
	if not mat:
		return 0

	leg = "%02d"%int(mat.group(1))
	docno = "%05d"%int(mat.group(2))
	rn = docno[:3]

	openURL("http://dip21.bundestag.de/dip21/btd/"
		"%(leg)s/%(rn)s/%(leg)s%(docno)s.pdf"%locals())
	return 1


def main():
	root = tkinter.Tk()
	root.title("onelinecli")
	olc = OneLineCli(root)
	olc.pack()
	root.geometry("+100+50")
	olc.update_idletasks()

	root.mainloop()
	root.withdraw()

	command = olc.getCommand()
	if not command:
		sys.exit()

	olc.saveHistory()

	for name, val in globals().items():
		if name.startswith("handle_"):
			if val(command):
				sys.exit(0)

	if not re.search("&\s*$",command):
		command = command+"&"
	os.system(command)


if __name__=="__main__":
	main()
