/*
 *	On-screen Display
 *
 *	(c) 2020--2021 Jiri Kalvoda <jirikalvoda@kam.mff.cuni.cz>
 */

#include "osdd-file.h"
#include "util.h"
#include "osdd-to-string.h"

#include <stdio.h>
#include <string.h>
#include <getopt.h>
#include <stdlib.h>



// *************************  STATE STRUCT **********

struct file_state
{
	char * file_name;
	char * open_mode;
	struct osd_to_string_state to_string;
	bool end_by_null_char;
};

// *************************  MAIN FUNCTIONS *******

static
void file_write(struct file_state *state, VECTOR(char) out)
{
	if(!out) return;
	FILE * f = fopen(state->file_name,state->open_mode);
	if(f)
	{
		fprintf(f,"%s", out);
		if(state->end_by_null_char)
			putc(0, f);
		fclose(f);
	}
	VFREE(out);
}

CREATE_FUNC_USING_TO_STRING(file)

// *************************  NEW ******************

static
void file_new_help(FILE * f)
{
	fprintf(f,"\
Module FILE help:\n\
-a, --append \t\tAppend to file (do not overwrite)\n\
-n, --end-by-null-char\tAppend \\0 to end of each message\n\
" OSDD_TO_STRING_HELP "\
\n\
");
}

static 
struct osd_abstract file_new(int argc, char ** argv, Display * nope)
{
	(void)nope;
	argc++;argv--;
	struct osd_abstract r;
	static const char short_opts[] = "+b+n" OSDD_TO_STRING_SHORTOP;
	static const struct option long_opts[] = {
		{ "append",		no_argument,	NULL,	'b' },
		{ "end-by-null-char",		no_argument,	NULL,	'n' },
		OSDD_TO_STRING_LONGOP
		{ NULL,		0,			NULL,	0   },
	};
	memset(&r,0,sizeof(r));
	struct file_state *state = xmalloc(sizeof(*state));
	memset(state,0,sizeof(state)[0]);

	state->open_mode = "w";
	osd_to_string_state_init(&state->to_string);

	int opt;
	optind = 0;
	while ((opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) >= 0)
	{
		if(!osd_to_string_parse_arg(&state->to_string,opt))
		switch (opt)
		{
			case 'b':
				state->open_mode = "a";
				break;
			case 'n':
				state->end_by_null_char = true;
				break;
			default:
				fprintf(stderr,"Option %c not exist\n\n",opt);
				file_new_help(stderr);
				exit(0);
		}
	}
	int ind = optind;
	if(ind >= argc)
	{
		fprintf(stderr,"Missing positional argument\n\n");
		file_new_help(stderr);
		exit(0);
	}
	state->file_name = argv[ind++];
	if(ind != argc)
	{
		fprintf(stderr,"Too many arguments\n\n");
		file_new_help(stderr);
		exit(0);

	}

	ADD_FUNC_TO_ABSTRACT(r, file)
	return r;
}

// *************************  CREATOR ****************************

CREATE_STANDARD_CREATOR(file, "FILE")