/*
 * configuration.h: logapp configuration header
 *
 *
 * Copyright (C) 2007-2010 Michael Brunner <mibru@gmx.de>
 *
 * This program 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 2
 * of the License, or (at your option) any later version.
 *
 *
 * This program 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
 * General Public License for more details.
 */

#ifndef __CONFIGURATION_H__
#define __CONFIGURATION_H__

#include "logapp.h"

#include <stdlib.h>
#include <regex.h>
#include <pthread.h>

#include <sys/time.h>


typedef struct {
	char* argprefix;	/* always handle arguments starting with this
				   prefix */
	char* strip_prefix;	/* strip prefix from called executable
				   filename */
	char* executable;	/* logapp executable filename */
	int   usepty;		/* use ptys to redirect streams */
	int   dumbterm;		/* term is not able to handle escape codes */
	int   detectescape;	/* this option enables escape sequence
				   detection for stdout and stderr */
	int   ptyremovecr;	/* remove CR read from PTY */
	int   appendlog;	/* append to log file */
	int   printsummary;	/* print execution summary */
	int   printlogname;	/* show used logfile after execution */
	int   disable;		/* disable output handling */
	char* disable_keywords; /* keywords the disable output handling when
				   found in the application parameter list */
	char* logname;		/* application output log */
	int   logtime;		/* add timestamp to each logged line */
	char* logtimerstregexp; /* regexp to reset logged time */
	regex_t plogtimerstreg; /* preprocessed regexp to reset logged time */
	int   logreltime;       /* log relative times */
	int   logenv;		/* add environment variables to logfile */
	int   maxlogsize;       /* maximum logfile size in KiB */
	int   locklogfile;      /* lock logfile when opening it */
	int   warnlogfilelock;  /* show message if logfile is locked */
	int   maxlogfiles;	/* maximum number of logfiles open at a time */
	int   circularlog;      /* reuse same logfile in a circular way */ 
	int   logrename;	/* rename logfile before truncating it */
	int   alignlog;		/* start a new line for every logged item even
				   in charbased mode */
	int   jointimeout;	/* join timeout for char based packets */
	int   alignlinebreaks;  /* Align lines to the left in the logfile if
				   timestamps are added */
	char* configfile;	/* current config file */
	char* configsection;	/* manually selected section in config file */
	char* custconfigfile;	/* custom config file */
	char* preexeccmd;	/* command to be executed before application
				   is started */
	char* postexeccmd;	/* command to be executed after application
				  is started */
	int   exitonexecfail;	/* exit if execution of command fails */
	int   extregexp;	/* use extended regexp syntax */
} config_t;

extern config_t config;

typedef struct {
	char*	start;
	int	len;
	char*	end;
	char*	read;
} readbuf_t;

typedef struct {
	int	fh;	/* pipe file handle */
	int	cfhno;	/* numerical console file handle */
	char*   name;   /* visible pipe name */
	pthread_t ct;   /* capture thread */
	char*   dbuf;   /* physical data buffer pointed to by other buffers */
	char*	buf;	/* char buffer */
	readbuf_t rdbuf; /* used in linebased mode for faster read */
	int	state;  /* read return state */
	int     charbased; /* work character based instead of linebased */
	int	(*handler)(void*); /* Pointer to stream handler */
	int	detectescape; /* switch stream to charbased mode if an escape
				 sequence is detected */
	int	switchtocbmode; /* escape has bin detected, now switch to 
				   charbased mode as soon as possible */
	int	memcr;  /* temporary stored CR */
	int     ptyremovecr; /* remove carriage return from CR-LF */

	int	blen;	/* buffer length (1 will be added for overhead) */
	int	bfill;  /* number of characters currently buffered */
	int	recalclen; /* recalculate line length */
	int	fgcol;  /* foreground console text color */
	int	bgcol;  /* background console text color */
	int	bold;   /* bold console font */

	int	clip;   /* clip console output after x chars */
	int	eclip;  /* enable clipping: 0 disable, 1 enable, 2 auto */
	char*   escreset; /* Escape sequence to reset the console */
	int	escresetlen;
	char*   esccolor; /* Escape sequence to set color attribute */
	int	esccolorlen;
	
	int	linecount; /* count line passed to stream */
	char*   lineprefix; /* prefix for each line in logfile */
	int	lineprefixlen;
#define LINEBREAKBUFSIZE	8
	int	linebreakpos[LINEBREAKBUFSIZE + 1]; /* buffer to store already
						       detected linebreaks */

	char*   regexp; /* regular expression */
	regex_t preg;	/* preprocessed regular expression */
	int     regbgcol; /* background console text color for regexp */
	char*   bgesccolor; /* Pointer to escape bg color attribute */
	char*   execregexp; /* regular expression for command execution */
	regex_t pexecreg; /* preprocessed regular expression for command 
			     execution */
	char*   execcommand; /* command to be executed after regexp match */
} pipe_t; 

extern pipe_t pstdout;
extern pipe_t pstderr;

typedef struct {
	int	fh;		/* file handle */
	char*   name;		/* file name */
	unsigned sizelimit;	/* max size */
	char*   oldext;		/* extension to add when renaming logfile */
	int	appendnr;	/* number added to filename (is increased if
				   file is locked by another process; 0 means
				   no number is added) */
	char*   head;		/* prefix for logfile header lines */
	char*   split;		/* prefix for logfile split marker lines */
	char*   foot;		/* prefix for logfile footer lines */
	int     addnewline;     /* add newline before next log write */ 
	char*   indent;		/* prefix for indenting logfile lines */
} logfile_t; 

extern logfile_t logfile;

typedef struct {
	char*	exe;		/* application to be run */
	char**	argv;		/* application argv array */
	int	argc;		/* application arg count */
	pid_t	pid;		/* child application pid */
	int	active;		/* application active */
	int	doexit;		/* application has received signal to exit */
	int	exit_state;	/* exit state after application terminated */
	time_t  starttime;	/* time the application has been started */
	struct timeval toffset; /* time offset for timestamp calculation */
	pipe_t*	pstdout;	/* application stdout pipe */
	pipe_t*	pstderr;	/* application stderr pipe */
	struct winsize* ptysize; /* PTY window size */
	struct termios* ptytermios; /* PTY terminal io attributes */
	struct termios* ptytermios_bak; /* orig. PTY terminal io attributes */
	logfile_t* logfile;	/* logfile handle */
} app_t;

typedef struct {
	char* 	string;
	int	value;
} stringvalue_t;

extern app_t app;

extern int	show_usage;
extern int	show_version;
extern int	show_config;

/* possible argument values */
typedef enum {
	TBOOL,
	TCLIP,
	TCOLOR,
	TINT,
	TNONE,
	TSTRING,
	TUINT,
} t_vartype;

typedef struct {
	char		shrt;	/* one char argument */
	char*		lng;	/* long argument name */
	char*   	parm;	/* value description */
	t_vartype 	type;	/* value type */
	void*		var;	/* pointer to config variable */
	char*		desc;	/* argument description */
	int		set;	/* provided as commandline argument */
} arglist_t;

extern arglist_t arglist[];

extern const int arglistsize;

extern int parse_args(int argc, char* argv[]);
extern void show_configuration(void);
extern int get_config(void);
extern int fixup_config(void);
extern void cleanup_config(void);
extern int get_display_parameters(void);
extern int adjust_clipping(void);
extern int check_for_disable_keywords(void);
extern char* get_longpath(const char* filename);

#endif /* __CONFIGURATION_H__ */
