/* Main */

/*
 * This file is part of gapk (GSM Audio Pocket Knife).
 *
 * gapk is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * gapk is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with gapk.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>

#include <sys/socket.h>
#include <netinet/in.h>

#include <osmocom/core/socket.h>

#include <gapk/codecs.h>
#include <gapk/formats.h>
#include <gapk/procqueue.h>


struct gapk_options
{
	const char *fname_in;
	struct {
		const char *hostname;
		uint16_t port;
	} rtp_in;
	const struct format_desc *fmt_in;

	const char *fname_out;
	struct {
		const char *hostname;
		uint16_t port;
	} rtp_out;
	const struct format_desc *fmt_out;
};

struct gapk_state
{
	struct gapk_options opts;

	struct pq *pq;

	struct {
		struct {
			FILE *fh;
		} file;
		struct {
			int fd;
		} rtp;
	} in;

	struct {
		struct {
			FILE *fh;
		} file;
		struct {
			int fd;
		} rtp;
	} out;
};


static void
print_help(char *progname)
{
	int i;

	/* Header */
	fprintf(stdout, "Usage: %s [options]\n", progname);
	fprintf(stdout, "\n");
	fprintf(stdout, "Options:\n");
	fprintf(stdout, "  -i, --input-file=FILE\t\tInput file\n");
	fprintf(stdout, "  -I, --input-rtp=HOST/PORT\t\tInput RTP stream\n");
	fprintf(stdout, "  -o, --output-file=FILE\tOutput file\n");
	fprintf(stdout, "  -O, --output-rtp=HOST/PORT\tOutput RTP stream\n");
	fprintf(stdout, "  -f, --input-format=FMT\tInput format (see below)\n");
	fprintf(stdout, "  -g, --output-format=FMT\tOutput format (see below)\n");
	fprintf(stdout, "\n");

	/* Print all codecs */
	fprintf(stdout, "Supported codecs:\n");
	fprintf(stdout, " name\tfmt enc dec\tdescription\n");

	for (i=CODEC_INVALID+1; i<_CODEC_MAX; i++) {
		const struct codec_desc *codec = codec_get_from_type(i);
		fprintf(stdout, " %s\t %c   %c   %c\t%s\n",
			codec->name,
			'*',
			codec->codec_encode ? '*' : ' ',
			codec->codec_decode ? '*' : ' ',
			codec->description
		);
	}

	fprintf(stdout, "\n");

	/* Print all formats */
	fprintf(stdout, "Supported formats:\n");
	
	for (i=FMT_INVALID+1; i<_FMT_MAX; i++) {
		const struct format_desc *fmt = fmt_get_from_type(i);
		fprintf(stdout, " %s%s%s\t%s\n",
			fmt->name,
			strlen(fmt->name) <  7 ? "\t" : "",
			strlen(fmt->name) < 15 ? "\t" : "",
			fmt->description
		);
	}

	fprintf(stdout, "\n");
}

static int
parse_host_port(const char *host_port, const char **host)
{
	char *dup = strdup(host_port);
	char *tok;

	if (!dup)
		return -ENOMEM;

	tok = strtok(dup, "/");
	if (!tok)
		return -EINVAL;
	*host = tok;

	tok = strtok(NULL, "/");
	if (!tok)
		return -EINVAL;

	return atoi(tok);
}

static int
parse_options(struct gapk_state *state, int argc, char *argv[])
{
	const struct option long_options[] = {
		{"input-file", 1, 0, 'i'},
		{"output-file", 1, 0, 'o'},
		{"input-rtp", 1, 0, 'I'},
		{"output-rtp", 1, 0, 'O'},
		{"input-format", 1, 0, 'f'},
		{"output-format", 1, 0, 'g'},
		{"help", 0, 0, 'h'},
	};
	const char *short_options = "i:o:I:O:f:g:h";

	struct gapk_options *opt = &state->opts;

	/* Set some defaults */
	memset(opt, 0x00, sizeof(*opt));

	/* Parse */
	while (1) {
		int c, rv;
		int opt_idx;

		c = getopt_long(
			argc, argv, short_options, long_options, &opt_idx);
		if (c == -1)
			break;

		switch (c) {
		case 'i':
			opt->fname_in = optarg;
			break;

		case 'o':
			opt->fname_out = optarg;
			break;

		case 'I':
			rv = parse_host_port(optarg, &opt->rtp_in.hostname);
			if (rv < 0 || rv > 0xffff) {
				fprintf(stderr, "[!] Invalid port: %d\n", rv);
				return -EINVAL;
			}
			opt->rtp_in.port = rv;
			break;

		case 'O':
			rv = parse_host_port(optarg, &opt->rtp_out.hostname);
			if (rv < 0 || rv > 0xffff) {
				fprintf(stderr, "[!] Invalid port: %d\n", rv);
				return -EINVAL;
			}
			opt->rtp_out.port = rv;
			break;

		case 'f':
			opt->fmt_in = fmt_get_from_name(optarg);
			if (!opt->fmt_in) {
				fprintf(stderr, "[!] Unsupported format: %s\n", optarg);
				return -EINVAL;
			}
			break;

		case 'g':
			opt->fmt_out = fmt_get_from_name(optarg);
			if (!opt->fmt_out) {
				fprintf(stderr, "[!] Unsupported format: %s\n", optarg);
				return -EINVAL;
			}
			break;

		case 'h':
			return 1;

		default:
			fprintf(stderr, "[+] Unknown option\n");
			return -EINVAL;

		}
	}

	return 0;
}

static int
check_options(struct gapk_state *gs)
{
	/* Required formats */
	if (!gs->opts.fmt_in || !gs->opts.fmt_out) {
		fprintf(stderr, "[!] Input and output formats are required arguments !\n");
		return -EINVAL;
	}

	/* Transcoding */
	if (gs->opts.fmt_in->codec_type != gs->opts.fmt_out->codec_type) {
		const struct codec_desc *codec;

		/* Check source codec */
		codec = codec_get_from_type(gs->opts.fmt_in->codec_type);
		if (!codec) {
			fprintf(stderr, "[!] Internal error: bad codec reference\n");
			return -EINVAL;
		}
		if ((codec->type != CODEC_PCM) && !codec->codec_decode) {
			fprintf(stderr, "[!] Decoding from '%s' codec is unsupported\n", codec->name);
			return -ENOTSUP;
		}

		/* Check destination codec */
		codec = codec_get_from_type(gs->opts.fmt_out->codec_type);
		if (!codec) {
			fprintf(stderr, "[!] Internal error: bad codec reference\n");
			return -EINVAL;
		}
		if ((codec->type != CODEC_PCM) && !codec->codec_encode) {
			fprintf(stderr, "[!] Encoding to '%s' codec is unsupported\n", codec->name);
			return -ENOTSUP;
		}
	}

	/* Input combinations */
	if (gs->opts.fname_in && gs->opts.rtp_in.port) {
		fprintf(stderr, "[!] You have to decide on either file or RTP input\n");
		return -EINVAL;
	}

	/* Output combinations */
	if (gs->opts.fname_out && gs->opts.rtp_out.port) {
		fprintf(stderr, "[!] You have to decide on either file or RTP output\n");
		return -EINVAL;
	}

	return 0;
}

static int
files_open(struct gapk_state *gs)
{
	if (gs->opts.fname_in) {
		gs->in.file.fh = fopen(gs->opts.fname_in, "rb");
		if (!gs->in.file.fh) {
			fprintf(stderr, "[!] Error while opening input file for reading\n");
			perror("fopen");
			return -errno;
		}
	} else if (gs->opts.rtp_in.port) {
		gs->in.rtp.fd = osmo_sock_init(AF_UNSPEC, SOCK_DGRAM,
						IPPROTO_UDP,
						gs->opts.rtp_in.hostname,
						gs->opts.rtp_in.port,
						OSMO_SOCK_F_BIND);
		if (gs->in.rtp.fd < 0) {
			fprintf(stderr, "[!] Error while opening input socket\n");
			return gs->in.rtp.fd;
		}
	} else
		gs->in.file.fh = stdin;

	if (gs->opts.fname_out) {
		gs->out.file.fh = fopen(gs->opts.fname_out, "wb");
		if (!gs->out.file.fh) {
			fprintf(stderr, "[!] Error while opening output file for writing\n");
			perror("fopen");
			return -errno;
		}
	} else if (gs->opts.rtp_out.port) {
		gs->out.rtp.fd = osmo_sock_init(AF_UNSPEC, SOCK_DGRAM,
						IPPROTO_UDP,
						gs->opts.rtp_out.hostname,
						gs->opts.rtp_out.port,
						OSMO_SOCK_F_CONNECT);
		if (gs->out.rtp.fd < 0) {
			fprintf(stderr, "[!] Error while opening output socket\n");
			return gs->out.rtp.fd;
		}
	} else
		gs->out.file.fh = stdout;

	return 0;
}

static void
files_close(struct gapk_state *gs)
{
	if (gs->in.file.fh && gs->in.file.fh != stdin)
		fclose(gs->in.file.fh);
	if (gs->in.rtp.fd >= 0)
		close(gs->in.rtp.fd);
	if (gs->out.file.fh && gs->out.file.fh != stdout)
		fclose(gs->out.file.fh);
	if (gs->out.rtp.fd >= 0)
		close(gs->out.rtp.fd);
}

static int
handle_headers(struct gapk_state *gs)
{
	int rv;
	unsigned int len;

	/* Input file header (remove & check it) */
	len = gs->opts.fmt_in->header_len;
	if (len && gs->in.file.fh) {
		uint8_t *buf;
		
		buf = malloc(len);
		if (!buf)
			return -ENOMEM;

		rv = fread(buf, len, 1, gs->in.file.fh);
		if ((rv != 1) ||
		    memcmp(buf, gs->opts.fmt_in->header, len))
		{
			free(buf);
			fprintf(stderr, "[!] Invalid header in input file");
			return -EINVAL;
		}

		free(buf);
	}

	/* Output file header (write it) */
	len = gs->opts.fmt_out->header_len;
	if (len && gs->out.file.fh) {
		rv = fwrite(gs->opts.fmt_out->header, len, 1, gs->out.file.fh);
		if (rv != 1)
			return -ENOSPC;
	}

	return 0;
}

static int
make_processing_chain(struct gapk_state *gs)
{
	const struct format_desc *fmt_in, *fmt_out;
	const struct codec_desc *codec_in, *codec_out;

	int need_dec, need_enc;

	fmt_in  = gs->opts.fmt_in;
	fmt_out = gs->opts.fmt_out;

	codec_in  = codec_get_from_type(fmt_in->codec_type);
	codec_out = codec_get_from_type(fmt_out->codec_type);

	need_dec = (fmt_in->codec_type != CODEC_PCM) &&
	           (fmt_in->codec_type != fmt_out->codec_type);
	need_enc = (fmt_out->codec_type != CODEC_PCM) &&
	           (fmt_out->codec_type != fmt_in->codec_type);

	/* File read */
	if (gs->in.file.fh)
		pq_queue_file_input(gs->pq, gs->in.file.fh, fmt_in->frame_len);
	else
		pq_queue_rtp_input(gs->pq, gs->in.rtp.fd, fmt_in->frame_len);

	/* Decoding to PCM ? */
	if (need_dec)
	{
		/* Convert input to decoder input fmt */
		if (fmt_in->type != codec_in->codec_dec_format_type)
		{
			const struct format_desc *fmt_dec;

			fmt_dec = fmt_get_from_type(codec_in->codec_dec_format_type);
			if (!fmt_dec)
				return -EINVAL;

			pq_queue_fmt_convert(gs->pq, fmt_in, 0);
			pq_queue_fmt_convert(gs->pq, fmt_dec, 1);
		}

		/* Do decoding */
		pq_queue_codec(gs->pq, codec_in, 0);
	}
	else if (fmt_in->type != fmt_out->type)
	{
		/* Convert input to canonical fmt */
		pq_queue_fmt_convert(gs->pq, fmt_in, 0);
	}

	/* Encoding from PCM ? */
	if (need_enc)
	{
		/* Do encoding */
		pq_queue_codec(gs->pq, codec_out, 1);

		/* Convert encoder output to output fmt */
		if (fmt_out->type != codec_out->codec_enc_format_type)
		{
			const struct format_desc *fmt_enc;

			fmt_enc = fmt_get_from_type(codec_out->codec_enc_format_type);
			if (!fmt_enc)
				return -EINVAL;

			pq_queue_fmt_convert(gs->pq, fmt_enc, 0);
			pq_queue_fmt_convert(gs->pq, fmt_out, 1);
		}
	}
	else if (fmt_in->type != fmt_out->type)
	{
		/* Convert canonical to output fmt */
		pq_queue_fmt_convert(gs->pq, fmt_out, 1);
	}

	/* File write */
	if (gs->out.file.fh)
		pq_queue_file_output(gs->pq, gs->out.file.fh, fmt_out->frame_len);
	else
		pq_queue_rtp_output(gs->pq, gs->out.rtp.fd, fmt_out->frame_len);

	return 0;
}

static int
run(struct gapk_state *gs)
{
	int rv, frames;

	rv = pq_prepare(gs->pq);
	if (rv)
		return rv;

	for (frames=0; !(rv = pq_execute(gs->pq)); frames++);

	fprintf(stderr, "[+] Processed %d frames\n", frames);

	return frames > 0 ? 0 : rv;
}

int main(int argc, char *argv[])
{
	struct gapk_state _gs, *gs = &_gs;
	int rv;

	/* Clear state */
	memset(gs, 0x00, sizeof(struct gapk_state));
	gs->in.rtp.fd = -1;
	gs->out.rtp.fd = -1;

	/* Parse / check options */
	rv = parse_options(gs, argc, argv);
	if (rv > 0) {
		print_help(argv[0]);
		return 0;
	}
	if (rv < 0)
		return rv;

	/* Check request */
	rv = check_options(gs);
	if (rv)
		return rv;

	/* Create processing queue */
	gs->pq = pq_create();
	if (!gs->pq) {
		rv = -ENOMEM;
		goto error;
	}

	/* Open source / destination files */
	rv = files_open(gs);
	if (rv)
		goto error;

	/* Handle input/output headers */
	rv = handle_headers(gs);
	if (rv)
		goto error;

	/* Make processing chain */
	rv = make_processing_chain(gs);
	if (rv)
		goto error;

	/* Run the processing queue */
	rv = run(gs);

error:
	/* Close source / destination files */
	files_close(gs);

	/* Release processing queue */
	pq_destroy(gs->pq);
	
	return rv;
}
