# Folder structure:
# GPSTools/
#   ├─ pythonTools
#   │   └─ DSD
#   │       ├─ dat64L.py
#   │       ├─ hp8648C.py
#   │       ├─ simple_test_cube_control.py
#   │       └─ simple_chirp_jammer_control.py
#   └─ AntiJamTest
#       ├─ server_main
#       ├─ server_control_spirent
#       ├─ server_control_jammer
#       │   ├─ server.py
#       │   └─ web
#       │       └─ app
#       │           └─ app.py
#       └─ server_control_hackrf

from flask import Flask, render_template, request, jsonify
from flask_httpauth import HTTPBasicAuth
from waitress import serve
import multiprocessing.connection as mp_con
from logging.config import dictConfig

dictConfig(
    {
        "version": 1,
        "formatters": {
            "default": {
                "format": "[%(asctime)s] %(levelname)s in %(module)s: %(message)s",
            }
        },
        "handlers": {
            "console": {
                "class": "logging.StreamHandler",
                "stream": "ext://sys.stdout",
                "formatter": "default",
            },
            "size-rotate": {
                "class": "logging.handlers.RotatingFileHandler",
                "filename": "flask.log",
                "maxBytes": 5000000,
                "backupCount": 1,
                "formatter": "default",
            },
        },
        "root": {"level": "INFO",
            "handlers": ["console", "size-rotate"]
        },
    }
)

app = Flask(__name__)

auth = HTTPBasicAuth()
user = {'username':'username','password':'password'}


@auth.verify_password
def verify_password(username, password):
    if username == user['username'] and password == user['password']:
      return True
    else:
      return False


def msg_send_recv( x ):
    '''Inputs:  x = string - message to be sent to client
              msg_addr = string - client ip address
    '''  
    control_port = 10001
    msg_addr = ('localhost',control_port)

    result = {}
    try:
        client = mp_con.Client(msg_addr)
        client.send(x)
        result = client.recv()
        client.close()
    except:
        app.logger.error("msg_send_recv error {}".format(x))
        pass
    return result

def msg_send( x ):
    
    control_port = 10001
    msg_addr = ('localhost',control_port)

    client = mp_con.Client(msg_addr)
    client.send(x)
    client.close()


@app.route("/site-map", methods=['GET'])
def siteMap():
  fn = 'siteMap'
  ip_addr = request.remote_addr
  app.logger.info(fn+':: GET request from '+ ip_addr)
  
  data_dict = {}
  f = open('app.py','r')
  fs = f.readlines()
  for l in fs:
    if l[:len('@app.route(')] == '@app.route(':
      url = l.split('"')[1]
      data_dict[ str("{:s}".format(url)) ] = ""
  host_url = request.host_url
  return render_template('site_map.html', data=data_dict, host=host_url[:-1])


def getHP8648CStatus(gdib_address):
  fn = 'getHP8648CStatus()'
  ip_addr = request.remote_addr
  app.logger.info(fn+':: GET request from '+ ip_addr)
  return msg_send_recv(['getHP8648CStatus',str(gdib_address)])

@app.route("/api/v1/hp8648c/getStatus/16", methods=['GET'])
def getHP8648CStatus16():
  return getHP8648CStatus(16)

@app.route("/api/v1/hp8648c/getStatus/18", methods=['GET'])
def getHP8648CStatus18():
  return getHP8648CStatus(18)

def getdat64LStatus(dat64_port=4):
  fn = 'getdat64LStatus()'
  ip_addr = request.remote_addr
  app.logger.info(fn+':: GET request from '+ ip_addr)
  return msg_send_recv(['getDat64LStatus',str(dat64_port)])

@app.route("/api/v1/dat64l/getStatus/4", methods=['GET'])
def getdat64LStatus4():
  return getdat64LStatus(4)

@app.route("/api/v1/dat64l/getStatus/22", methods=['GET'])
def getdat64LStatus22():
  return getdat64LStatus(22)

@app.route("/api/v1/dat64l/getStatus/19", methods=['GET'])
def getdat64LStatus19():
  return getdat64LStatus(19)

@app.route("/api/v1/chirp/getStatus", methods=['GET'])
def getChirpStatus():
  fn = 'getChirpStatus()'
  ip_addr = request.remote_addr
  app.logger.info(fn+':: GET request from '+ ip_addr)
  return msg_send_recv(['getChirpStatus'])

@app.route("/api/v1/turnOnCW", methods=['GET', 'POST'])
@auth.login_required
def turnOnCW():
  fn = 'turnOnCW()'
  ip_addr = request.remote_addr
  app.logger.info(fn+':: GET request from '+ ip_addr)
  rt = None
  if request.method == 'POST':
    if 'addr' in request.form:
      app.logger.debug(fn+':: POST request with args from ' + ip_addr)
      d = {}
      d['input_addr'] = request.form['addr']
      d['input_power'] = request.form['power']
      d['input_freq'] = request.form['freq']
      rt = msg_send_recv(['turnOnCW', d['input_addr'], d['input_power'], d['input_freq']])
    else:
      app.logger.debug(fn+':: POST request without args from ' + ip_addr)
      return "Bad request", 400
  else:
    args = request.args
    if 'gpib_addr' in args:
      app.logger.debug(fn+':: GET request with args from ' + ip_addr)
      rt = msg_send_recv(['turnOnCW', args['gpib_addr'], args['pwr'], args['freq']])
    else:
      app.logger.debug(fn+':: GET request without args from ' + ip_addr)
      rt = msg_send_recv(['turnOnCW',  18, -35, 1575.42])
  
  return 'OK' if rt == True else 'Failed'

@app.route("/api/v1/turnOffAllCWs", methods=['GET', 'POST'])
@auth.login_required
def turnOffAllCWs():
  fn = 'turnOffAllCWs()'
  ip_addr = request.remote_addr
  app.logger.info(fn+':: GET request from '+ ip_addr)
  rt = True
  rt = rt & msg_send_recv(['turnOnCW',  16, -999.0, 1575.42])
  rt = rt & msg_send_recv(['turnOnCW',  18, -999.0, 1575.42])
  return 'OK' if rt else 'Failed'


@app.route("/api/v1/turnOnChirp", methods=['GET', 'POST'])
@auth.login_required
def turnOnChirp():
  fn = 'turnOnChirp()'
  ip_addr = request.remote_addr
  app.logger.info(fn+':: GET request from '+ ip_addr)
  rt = None
  args = request.args
  if 'com_port' in args and 'desired_pwr_dBm' in args and 'sec' in args:
    app.logger.debug(fn+':: GET request with args from ' + ip_addr)
    rt = msg_send_recv(['turnOnChirp', int(args['com_port']), float(args['desired_pwr_dBm']), int(args['sec'])])
  else:
    app.logger.debug(fn+':: GET request without args from ' + ip_addr)
    rt = msg_send_recv(['turnOnChirp',  21, -25, 30])
  app.logger.debug(fn+':: turnOnChirp returns ' + str(rt))
  return rt


@app.route("/api/v1/turnOffChirp", methods=['GET', 'POST'])
@auth.login_required
def turnOffChirp():
  fn = 'turnOffChirp()'
  ip_addr = request.remote_addr
  app.logger.info(fn+':: GET request from '+ ip_addr)
  rt = msg_send_recv(['turnOffChirp'])
  return rt


if __name__ == "__main__":

  web_port = 10002
  serve(app, host='0.0.0.0', port=web_port, threads=4) #WAITRESS!
