#!/usr/bin/env python

"""Command line interface to pyvxl. Installed in python/scripts as 'can'."""

import sys
import logging
import traceback
import socket
import select
import os
import subprocess
from argparse import ArgumentParser
from colorama import Fore, Style
from pyvxl import config
from pyvxl import CAN

__program__ = 'can'


def print_help():
    """Called by the command h or help."""
    helpcolor = Fore.RED + Style.BRIGHT
    helprst = Fore.RESET + Style.RESET_ALL
    # TODO: Convert this to a list and print(like it's being piped to less)
    print(helpcolor + 'Valid commands:')
    print('')
    print(' - Bus Manipulation -----------------------------------------------------------')
    print('  restart')
    print('     - Reconnects to the CAN bus. Useful if the error light on the CAN case is')
    print('       red.')
    print('')
    print('  send signal <-f> <signal> <value> ')
    print('     - Send the msg containing <signal> with the signal value = <value>.')
    print('       <-f> can be specified to send a value not defined in the dbc file.')
    print('       e.g., send signal system power mode run')
    print('        or    ""    ""   syspwrmd          ""')
    print('')
    print('  send message <msgID> <data>')
    print('     - Send a complete message similar to the way it is displayed in CANoe.')
    print('       <msgID> can be the hexadecimal id or full name of the message. <data>')
    print('       is the message data to be sent. If the data given is shorter than')
    print('       specified by the dlc in the database, \'0\'s will be appended to the')
    print('       left of the entered message data to make it the correct length.')
    print('       e.g., send message 0x10242040 02')
    print('        or    ""    ""      10242040 02')
    print('')
    print('  send diag <txMsgID> <data> <rxMsgID>')
    print('     - Send a diagnostic message and wait for a response. <txMsgID> is the')
    print('       message id or name to transmit from. <data> is the data which will')
    print('       be sent with that message. <rxMsgId> is the id or name of the')
    print('       message to wait for a response from.')
    print('')
    print('  send lastfound <signal|message> <value> ')
    print('     - Sends the last found signal or message with <value>.')
    print('       e.g., send lastfound message 02')
    print('        or    ""     ""     signal run')
    print('')
    print('  wait <time> <msgId> [value]')
    print('     - Waits for <time>(ms) for msgId with value to be received. \'*\' can be')
    print('       used as a dont care. Returns 1 if found, else 0.')
    print('       e.g., wait 1000 0x10242040')
    print('              ""   ""      ""     02')
    print('              ""   ""      ""     *2')
    print('')
    print('  stop <signal|msgID>')
    print('     - Stops sending a periodic message')
    print('       e.g., stop system power mode')
    print('             stop syspwrmd')
    print('             stop 0x10242040')
    print('')
    print('  stopnode <node>')
    print('     - Stops all periodic messages sent from <node>')
    print('')
    print('  stopall')
    print('     - Stops all periodic messages')
    print('')
    print(' - Database & Bus Information -------------------------------------------------')
    print('')
    print('  config')
    print('     - Print the current vector hardware configuration')
    print('')
    print('  find node <string>')
    print('     - Prints all nodes found with <string> in their name')
    print('')
    print('  find message <string>')
    print('     - Prints all messages found with <string> in their name')
    print('')
    print('  find signal <string>')
    print('     - Prints all signals found with <string> in their name')
    print('')
    print('  periodics [info]')
    print('     - Prints all periodic messages being sent. If \'info\' is present, signals')
    print('       of each periodic and their values are also printed.')
    print('')
    print('  periodics info <val>')
    print('     - Prints current periodics including signal values. <val> can be either a')
    print('       message id, part of a message name, or part of a signal name.')
    print('')
    print('  log <command> [file]')
    print('     - Controls logging to [file]. <command> can be either \'start\' or \'stop\'.')
    print('       If [filename] is not specified, a default name will be chosen.')
    print('')
    print(' - Other ----------------------------------------------------------------------')
    print('  exit | ctrl+c | q     - Exit the app')
    print('  h | help              - Display this message'+helprst)

def main():
    """This script is intended to test and demonstrate the functionality
       of the vector.py CANcase interface"""
    # pylint: disable=R0912,R0914
    parser = ArgumentParser(prog=__program__, description='A license free '+
                            'interface to the CAN bus')
    parser.add_argument('-v', '--verbose', action='store_true',
                        help="enable verbose output")
    parser.add_argument('-c', '--channel', help='the CAN channel or port to'+
                        ' connect to')
    parser.add_argument('-e', '--example-script', action='store_true',
                        help='prints the location of an example script and '+
                        'also runs it')
    parser.add_argument('-nl', '--network-listen', action='store_true',
                        help='start the program in network mode. it will then '+
                        'begin listening for commands on a port related to the'+
                        ' can channel')
    parser.add_argument('-ns', '--network-send', metavar='cmd', type=str,
                        nargs='+', help='commands to send to a separate '+
                        'instance of the program running in network mode')