
const NavHeaderError = require('./error');

function detect (buffer) {
	const s = buffer.indexOf("*SMSRC");
	return s != -1 ? s : false;
}

function parse (buffer) {
	let offset = buffer.indexOf("*SMSRC");

	if (offset == -1) {
		return; // undefined
	}

	function ascii (length, start = offset) {
// 		const start = offset;
		const end = start+length;
		offset = end;
// 		const v = buffer.subarray(start, end).toString('ascii');
// 		console.log("s, e", start, end, offset);
// 		console.log("v = ", v);
// 		return v;
		return buffer.subarray(start, end).toString('ascii');
	}

	const header = {
		header: (buf, ctx) => {
			const header = ascii(6);
			if (header != "*SMSRC") {
				throw new NavHeaderError("Expected SmartSource marker not found at position " + s, buf);
			}
		},

		blk_siz: (buf, ctx) => {
			return Number(ascii(4));
		},

		line: (buf, ctx) => {
			return ascii(30).trim();
		},

		shot: (buf, ctx) => {
			return Number(ascii(10));
		},

		mask: (buf, ctx) => {
			return Number(ascii(2));
		},

		trg_mode: (buf, ctx) => {
			const trg_mode = ascii(1);
			switch (trg_mode) {
				case "I":
					return "internal";
				case "E":
					return "external";
				default:
					throw new NavHeaderError("Unknown SmartSource trigger mode: " + trg_mode, buf);
			}
		},

		time: (buf, ctx) => {
			const time = ascii(17);
			'20/08/30:05:45:58'
			return new Date(time.replace(/(\d{2})\/(\d{2})\/(\d{2}):(\d{2}):(\d{2}):(\d{2})/, "20$1-$2-$3T$4:$5:$6Z"));
		},

		src_number: (buf, ctx) => {
			return Number(ascii(1));
		},

		num_subarray: (buf, ctx) => {
			return Number(ascii(1));
		},

		num_guns: (buf, ctx) => {
			return Number(ascii(2));
		},

		num_active: (buf, ctx) => {
			return Number(ascii(2));
		},

		num_delta: (buf, ctx) => {
			return Number(ascii(2));
		},

		num_auto: (buf, ctx) => {
			return Number(ascii(2));
		},

		num_nofire: (buf, ctx) => {
			return Number(ascii(2));
		},

		spread: (buf, ctx) => {
			// Convert to ms
			return Number(ascii(4))/10;
		},

		volume: (buf, ctx) => {
			return Number(ascii(6));
		},

		avg_delta: (buf, ctx) => {
			return Number(ascii(5));
		},

		std_delta: (buf, ctx) => {
			return Number(ascii(5));
		},

		baroPress: (buf, ctx) => {
			// Converted to millibars
			return Number(ascii(6))/100;
		},

		manifold: (buf, ctx) => {
			return Number(ascii(4)); // PSI
		},

		spare: (buf, ctx) => {
			return ascii(88).trim();
		},
	};

	const gun = {
		string: (buf, ctx) => {
			return Number(ascii(1));
		},

		gun: (buf, ctx) => {
			return Number(ascii(2));
		},

		source: (buf, ctx) => {
			return Number(ascii(1));
		},

		mode: (buf, ctx) => {
			const v = ascii(1);
			switch (v) {
				case "A":
				case "M":
				case "O":
				case "D":
					return v;
				default:
					throw new NavHeaderError("Unrecognised SmartSource gun mode value: "+v, buf);
			}
		},

		detect: (buf, ctx) => {
			const v = ascii(1);
			switch (v) {
				case "P":
				case "Z":
				case "L":
					return v;
				default:
					throw new NavHeaderError("Unrecognised SmartSource detect value: "+v, buf);
			}
		},

		autofire: (buf, ctx) => {
			const v = ascii(1);
			switch (v) {
				case "N": return false;
				case "Y": return true;
				default:
					throw new NavHeaderError("Unrecognised SmartSource autofire value: "+v, buf);
			}
		},

		spare: (buf, ctx) => {
			return ascii(1).trim();
		},

		aimport: (buf, ctx) => {
			// Convert to ms
			return Number(ascii(6))/10;
		},

		firetime: (buf, ctx) => {
			// Convert to ms
			return Number(ascii(6))/10;
		},

		delay: (buf, ctx) => {
			// Convert to ms
			return Number(ascii(4))/10;
		},

		depth: (buf, ctx) => {
			// Convert to metres
			return Number(ascii(4))/10;
		},

		pressure: (buf, ctx) => {
			return Number(ascii(4));
		},

		volume: (buf, ctx) => {
			return Number(ascii(4));
		},

		filltime: (buf, ctx) => {
			return Number(ascii(4));
		}
	};


	const smartsource = {};
	smartsource._type = "smartsource";
	smartsource._received = new Date();
	for (const key of Object.keys(header)) {
		smartsource[key] = header[key](buffer, smartsource);
	}

	smartsource.guns = [];
	for (let n=0; n<smartsource.num_guns; n++) {
		const gunItem = [];
		for (const key of Object.keys(gun)) {
			gunItem.push(gun[key](buffer, gunItem));
		}
		smartsource.guns.push(gunItem);
	}

	return smartsource;

}

module.exports = {
	name: "SmartSource",
	detect,
	parse
};
