#! /usr/bin/python3
#
# Copyright (c) 2021 - Adjacent Link LLC, Bridgewater, New Jersey
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
#   notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
#   notice, this list of conditions and the following disclaimer in
#   the documentation and/or other materials provided with the
#   distribution.
# * Neither the name of Adjacent Link LLC nor the names of its
#   contributors may be used to endorse or promote products derived
#   from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#

from __future__ import absolute_import, division, print_function
import argparse
import matplotlib.pyplot as plt
import os
import sys
from etceanalyzers.mgen import to_dataframes


usagestr = 'Generate a strip chart of receptions vs time.'

suffix = 'network_receptions_stripchart'

parser = argparse.ArgumentParser(description=usagestr)

parser.add_argument('--graphfile',
                    metavar='GRAPHFILE',
                    action='store',
                    default=None,
                    help='The output graph file. Default is to rename ' \
                    'SQLITEFILE with a "%s.png" suffix.' % suffix)
parser.add_argument('--csvfile',
                    action='store_true',
                    default=False,
                    help='If specified, store the aggregated DataFrame ' \
                         'to csvfile.')
parser.add_argument('--keepselfrxs',
                    action='store_true',
                    default=False,
                    help='Do not remove self receptions from the analysis.')
parser.add_argument('--nodefilter',
                    default=None,
                    help='Colon separated list of receiver nodenames to plot. '
                    'Plots are limited to nodes specified.')
parser.add_argument('--height',
                    type=float,
                    action='store',
                    default=None,
                    help='Override graph height.')
parser.add_argument('--width',
                    type=float,
                    action='store',
                    default=None,
                    help='Override graph width.')
parser.add_argument('--margins',
                    metavar='MARGINS',
                    default='0.85:0.15:0.15:0.9',
                    help='Colon separated value of top:left:bottom:right graph ' \
                    'margins. Margins are expressed as a decimal from 0.0 to 1.0 ' \
                    'where the horizontal margin runs from left to right and the ' \
                    'vertical margin from bottom to top. So a bottom margin of 0.15 ' \
                    'is 15%% from the bottom of the page and a top margin of 0.8 is ' \
                    '20%% from the top of the page. Default: 0.85:0.15:0.15:0.9')
parser.add_argument('sqlitefile',
                    metavar='SQLITEFILE',
                    action='store',
                    help='An ETCE sqlite database.')

args = parser.parse_args()

if not os.path.isfile(args.sqlitefile):
    print('Could not find file "%s". Quitting.' % args.sqlitefile, file=sys.stderr)
    exit(1)

rx,_ = to_dataframes(args.sqlitefile, args.keepselfrxs)

rx['rxtimesec'] = rx.rxtime.apply(int)

rx['rxtimefrac'] = rx.rxtime - rx.rxtimesec

all_rxers = set(rx.rxnode.unique())

rxers = all_rxers

if args.nodefilter:
    # keep named nodes
    rxers = [nodename.strip() for nodename in args.nodefilter.split(':')]

    # filter out
    drop_rxers = all_rxers.difference(rxers)

    if drop_rxers:
        print('Dropping %s nodes, not included in nodefilter arg' % ','.join(sorted(drop_rxers)),
              file=sys.stderr)

    rx = rx.loc[rx.rxnode.isin(rxers)]

if args.csvfile:
    csvfile = \
        '.'.join(os.path.basename(args.sqlitefile).split('.')[:-1]) + \
        '-%s.csv' % suffix

    rx.to_csv(csvfile)

trials = sorted(rx.trial.unique())

ymax = rx.rxtimesec.max()

height = max(rx.rxtimesec.max() // 72, 6)
if args.height:
    height = args.height

width = 8.0
if args.width:
    width = args.width

top_margin, left_margin, bottom_margin, right_margin = \
    map(float, args.margins.split(':'))

for trial in trials:
    fig = plt.figure(figsize=(width, height))

    ax = fig.add_subplot(111)

    rx_trial = None

    try:
        rx_trial = rx[rx.trial == trial]
    except KeyError as ke:
        print(ke)
        continue

    rx_trial.plot(kind='scatter', x='rxtimefrac', y='rxtimesec', ax=ax, marker='.', s=0.5, color='black')

    ax.set_xlabel('rx time (fractional second)')

    ax.set_ylabel('rx time (second)')

    ax.set_ylim(0, ymax)

    ax.set_title('Receptions vs. Time')

    fig.subplots_adjust(top=top_margin,
                        left=left_margin,
                        bottom=bottom_margin,
                        right=right_margin)

    graphfile = '.'.join(os.path.basename(args.sqlitefile).split('.')[:-1]) + '-' + \
        suffix + \
        ('-trial_%02d.png' % trial)

    if args.graphfile:
        graphfile = args.graphfile % trial

    fig.savefig(graphfile)
