#!/usr/bin/python
#

import curses
import socket
import time
from retrypy import retry, check

socket_path = "/omd/sites/prod/tmp/run/live"

def mainloop(stdscr):
  curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)
  curses.init_pair(2, curses.COLOR_YELLOW, curses.COLOR_BLACK)
  try:
    curses.init_pair(3, 130, curses.COLOR_BLACK)
  except curses.error:
    curses.init_pair(3, curses.COLOR_CYAN, curses.COLOR_BLACK)
  curses.halfdelay(50)
  sy, sx = resize(stdscr)
  table = Table(['Host','Service','Status Detail','Chk'])
  while 1:
    table = fill_data(table)
    update_columns(stdscr, sy, sx, table)
    try:
      c = stdscr.getch()
    except curses.error:
      pass
    if c == ord('q'): 
      break
    elif c == curses.KEY_RESIZE:
      sy, sx = resize(stdscr)
    elif c == ord('b'):
      drawborder(stdscr, sy, sx)
    #elif c == ord('u'):
    #  update_columns(stdscr, sy, sx, table)
    #elif c == ord('r'):
    #  table = fill_data(table)

def resize(stdscr):
  y, x = stdscr.getmaxyx()
  curses.resizeterm(y, x)
  stdscr.clear()
  stdscr.refresh()  
  return y, x

def drawborder(stdscr, max_y, max_x):
  for a in range(0, max_x-1):
    stdscr.addch(0, a, ord('-'))
    stdscr.addch(max_y-1, a, ord('-'))
  for b in range(0, max_y-1):
    stdscr.addch(b, 0, ord('-'))
    stdscr.addch(b, max_x-1, ord('-'))

def update_columns(stdscr, max_y, max_x, table):
  #host, service, status, last checked
  #widths:
  #minimum: 5, 5, 10, 2
  #%ages: 22.7, 22.7, 45.5, 9 
  c1min = 5
  c2min = 5
  c3min = 10
  c4min = 2
  c1size = int(round(max_x * 0.227))
  c2size = int(round(max_x * 0.227))
  c3size = int(round(max_x * 0.455))
  c4size = int(round(max_x * 0.091))
  
  if c1size < c1min:
    c1size = c1min
  if c2size < c2min:
    c2size = c2min
  if c3size < c3min:
    c3size = c3min
  if c4size < c4min:
    c4size = c4min

  #define starts and ends
  c1s = 1
  c1e = c1s + c1size - 1
  c2s = c1e + 1
  c2e = c2s + c2size - 1
  c3s = c2e + 1
  c3e = c3s + c3size - 1
  c4s = c3e + 1
  c4e = c4s + c4size - 1

  #write column headers
  stdscr.erase()
  stdscr.addstr(0, c1s, table.columns[0][:c1size-1], curses.A_BOLD)
  stdscr.addstr(0, c2s, table.columns[1][:c2size-1], curses.A_BOLD)
  stdscr.addstr(0, c3s, table.columns[2][:c3size-1], curses.A_BOLD)
  stdscr.addstr(0, c4s, table.columns[3][:c4size-1], curses.A_BOLD)

  #take any row entry in table and display in columns
  r = 1
  for i in table.rows:
    if int(i[5]) == 1:
      c = 1
    elif int(i[5]) == 2:
      c = 2
    elif int(i[5]) == 3:
      c = 3
    else:
      c = 0

    stdscr.addstr(r, c1s, i[0][:c1size-1], curses.color_pair(c))
    stdscr.addstr(r, c2s, i[1][:c2size-1], curses.color_pair(c))
    stdscr.addstr(r, c3s, i[2][:c3size-1], curses.color_pair(c))
    stdscr.addstr(r, c4s, str(int(time.time())-int(i[3]))[:c4size-1], curses.color_pair(c))
    r += 1

  #stdscr.refresh()


class Table:
  #should be started with array of column names passed to it
  def __init__(self, columns):
    self.columns = columns
    self.rows = [] 

  #entry is an array of data in the row broken into columns
  def add_row(self, entry):
    self.rows.append(entry)

  def clear(self):
    self.rows[:] = []

def fill_data(table):

  data = get_check_data()

  table.clear()

  for i in data:
    table.add_row(i)
  
  for j in table.rows:
    if int(j[5]) == 1:
      j[5] = 2
    elif int(j[5]) == 2:
      j[5] = 1

  table.rows = sorted(table.rows, key=lambda x: x[5])

  #do some kind of thing to get the data
  #  table.add_row(['lamech.mikeit.com.au','Check_MK','CRIT - Cannot get data from TCP port 103.20.20.10:6556','40'])
  
  return table 

@retry.decorate(times=5, wait=lambda n: 2*n)
def get_check_data():
  sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  sock.connect(socket_path)
  sock.send("GET services\nFilter: state >= 1\nFilter: service_scheduled_downtime_depth = 0\nFilter: acknowledged = 0\nAnd: 3\nColumns: host_name description plugin_output service_last_check host_last_check state\n")
  sock.shutdown(socket.SHUT_WR)
  a = sock.recv(100000000)
  sock.close()

  chk_data = [ line.split(';') for line in a.split('\n')[:-1] ]

  return chk_data


curses.wrapper(mainloop)
