`#!/usr/bin/env node

'use strict'`

# Require the "nixfilter" module
nixfilter = require('nixfilter')

# Import/Require the "serialport" module
Serial_Port = require('serialport')
# Define the filter and register it on the module
nixfilter.filter module,
	description: 'Read from/write to a serial port'

	input_reader: nixfilter.reader.bytes()

	output_writer: nixfilter.writer.bytes()

	add_arguments: (argument_parser) ->
		argument_parser.addArgument ['--baud_rate', '--baudrate', '--baud', '-b'],
			type: 'int'
			choices: [75, 150, 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 230400, 460800, 921600]
			defaultValue: 115200
			help: 'The baud rate to use (default: 115200)'
		argument_parser.addArgument ['--data_bits', '--databits', '--bits', '-d'],
			type: 'int'
			choices: [7, 8]
			defaultValue: 8
			help: 'The number of data bits (default: 8)'
		argument_parser.addArgument ['--parity', '-p'],
			choices: ['none', 'even', 'mark', 'odd', 'space']
			defaultValue: 'none'
			help: 'The parity (default: none)'
		argument_parser.addArgument ['--stop_bits', '--stopbits', '-s'],
			type: 'int'
			choices: [1, 2]
			defaultValue: 1
			help: 'The number of stop bits (default: 1)'
		argument_parser.addArgument ['port'],
			help: 'The serial port to use. On Linux systems, this is usually something like "/dev/ttyUSB0".'
		return

	setup: (args) ->
		new Promise (resolve, reject) =>
			@serial_port = new Serial_Port args.port,
					baudRate: args.baud_rate
					dataBits: args.data_bits
					parity: args.parity
					stopBits: args.stop_bits
				, (error) =>
					if error
						reject(error)
					else
						@serial_port.on 'data', (data) =>
							@output(data)
							return
						@serial_port.on 'close', =>
							console.error "Serial port closed"
							@stop()
							return
						resolve()
					return
			return

	on_input: (byte_array) ->
		@serial_port.write byte_array, null, (error) =>
			if error
				console.error "Error writing to serial port: #{error.message}"
				@stop()
			return
		return

	terminate: ->
		new Promise (resolve, reject) =>
			@serial_port.close (error) =>
				if error
					reject(error)
				else
					resolve()
				return
			return

