# -*- coding: utf-8 -*-
# Insync Thunar Plugin
#
# Authors
# Brett Hartshorn <brett@insynchq.com>
# Luis Manuel R. Pugoy <lpugoy@insynchq.com>
#
# Copyright Insynchq Pte. Ltd., ("Insync") | http://www.insynchq.com
# License: GNU GPL v2

DEV_MODE = True

import gtk	# note Thunar is using GTK2
import json
import os
import socket
import sys
import thunarx
import urllib

#http://www.gtk.org/tutorial1.2/gtk_tut-13.html
#http://pygtk.org/docs/pygtk/class-gtkaction.html
#gtk.Action(name, label, tooltip, stock_id)

FS_ENCODING = sys.getfilesystemencoding()   # C is 'ANSI_X3.4-1968'

def ipc_insync(**kw):
  #print('<ipc-insync>',kw)
  data = json.dumps( kw )
  socket_file = u'/tmp/insync%r.sock' % os.getuid()
  if not os.path.exists(socket_file):
    if DEV_MODE:
      print('WARN: insync socket not found')
    return None
  sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  sock.settimeout(0.1)
  try:
    sock.connect(socket_file)
    sock.send(data)
    res = sock.recv(4096)
    sock.close()
  except:
    return None
  if res.strip():
    return json.loads(res.strip())
  else:
    return None


class InsyncPlugin(thunarx.MenuProvider):

  def __init__(self):
    self.file_list = dict()

  def do_action(self, menu, file, method):
    path = urllib.unquote(
      file.get_uri()[len('file://'):]
    )
    ipc_insync(method=method, full_path=path)

  def get_file_actions(self, window, files):
    if DEV_MODE:
      print('get file items', files)

    if len(files) != 1:
      # TODO what can we do with mutiple files here
      return None

    file = files[0]
    if file.get_uri_scheme() != 'file':
      return None

    path = os.path.realpath(urllib.unquote(file.get_uri()[len('file://'):]))
    path = unicode(path, FS_ENCODING)
    if DEV_MODE:
      print path
    is_dir = os.path.isdir(path)

    cm_info = ipc_insync(command='CONTEXT-MENU-ITEMS', full_path=path)

    if cm_info:
      title, self.cm_items = cm_info
      if is_dir:
        act = MyAction(
          name="Insync:folder",
          label=title,
          tooltip="Insync folder actions",
          stock_id=gtk.STOCK_DIRECTORY,
          menu_handler=self.submenu_callback_item,
          path=file
        )
      else:
        act = MyAction(
          name="Insync:file",
          label=title,
          tooltip="Insync file actions",
          stock_id=gtk.STOCK_FILE,
          menu_handler=self.submenu_callback_item,
          path=file
        )

      return [act]
    return None

  def submenu_callback_item(self, menu, file):
    if DEV_MODE:
      print('calling callback', menu, file)
    actions = []

    item_id = 0
    for text, cmd in self.cm_items:
      if text == 'separator':
        text = u'\u2015' * 10
        name = 'Insync:separator:' + str(item_id)
      else:
        name = 'Insync:%s:%d' % (text, item_id)
      item_id += 1
      act = gtk.Action(
        name=name,
        label=text,
        tooltip=text,
        stock_id=None
      )
      act.connect('activate', self.do_action, file, cmd)
      actions.append(act)
      subitem = act.create_menu_item()
      menu.append(subitem)
      subitem.show()

  # InfoProvider function to set emblems, but thunarx python doesn't have it
  def update_file_info(self, file):
    if file.get_uri_scheme() != 'file':
      return

    filename = urllib.unquote(file.get_uri()[len('file://'):])
    filename = os.path.realpath(filename)
    status = ipc_insync(command='GET-FILE-STATUS', full_path=filename)
    if DEV_MODE:
      print filename, status
    if status and status != 'UNKNOWN':
      emblem = _EMBLEM_KEYS[status]
      file.add_emblem(emblem)
      old_emblem = self.file_list.get(filename)
      self.file_list[filename] = emblem
      if old_emblem != emblem:
        file.invalidate_extension_info()
    elif self.file_list.pop(filename, None):
      file.invalidate_extension_info()


class MyAction(gtk.Action):

  __gtype_name__ = "MyAction"

  def __init__(self, name, label, tooltip=None, stock_id=None,
               menu_handler=None, path=None):
    gtk.Action.__init__(self, name, label, tooltip, stock_id)
    self.menu_handler = menu_handler
    self.path = path

  def create_menu_item(self):
    menuitem = gtk.MenuItem(self.get_label())

    if self.menu_handler is not None:
      menu = gtk.Menu()
      menuitem.set_submenu(menu)
      self.menu_handler(menu, self.path)

    return menuitem

  do_create_menu_item = create_menu_item
