/*
HTML washing functionality
  (used to be part of surgeweb level code, now also used by surgealert)

Example of use:
*/

#include "tcplib.h"
#include "defines.h"
#include "lib.h"

// *** Surgeweb message washing ( html (containing css) / text) ***
// --- 


typedef struct WASHPARAM {
	// Washing preferences
	int block_images;
	int proxy_http, block_http;
	char *ipnum;

	// Washing state flags
	int instyle;		// Whether we are within a multiline style block
	int inscript;		// Whether we are in a multiline script block
	int isend;			// Reached the end of the logical HTML 
	int inlink;			// Whether we are within a link definition of some kind
	int changes;		// Count of the page changes that were made
	int keep_eol;		// Keep line breaks in (for use of <pre> tags inside html messages)
	int last_was_text;	// If last tag was text then keep "\r\n" as " " to force word boundaries
	int last_text_char;	//  more comprehensive test of last_was_text
	int fancy_replies, last_was_blockquote;	// Cache a preference for speed
	int quote_level, done_quote, done_some;	// format-flowed output tracking
	int inhead;
	int debug_tag_count;
	int width_limit;	// Apply page width limit to large images
	int no_mpr;			// Treat MPR images as attachments
	int is_whitespace_pre;	// Support the tab type indentation that Chrome and Safari use

	// Text washing
	int last_was_div;	// If last tag was <div> then <br> has already been taken care of
	char *tag_base;		// Relative url as specified by base tag in message

	struct BUFIO_CSS *css_parser;	// For CSS washing
	void *data;			// arbitrary user pointer (Sw* generally)
    
    int insig;
    int inblock;

} WashParams;

typedef struct BUFIO_HTML {
	Buffer *buffer;		// Primary buffered IO processing buffer
	Html *parser;		// HTML parser data structure handle 
	int (*process)(void *d, Buffer *buffer, Html *h, FILE* fout, WashParams *params);	// Arbitrary processing function 
	WashParams *params;		// Arbitrary data pointer for use by processing function (SwWash *)
	FILE *fout;			// Output file handle (logically could be under params instead)
	void *data;			// arbitrary user pointer (Sw* generally)
} WashHtml;

typedef struct BUFIO_CSS {
	Buffer *buffer;		// Primary buffered IO processing buffer
	Css *parser;		// CSS parser data structure handle 
	int (*process)(void *d, Buffer *buffer, Css *h, FILE* fout);	// Arbitrary processing function 
//	WashParams *params;		// Arbitrary data pointer for use by processing function (SwWash *)
	FILE *fout;			// Output file handle (logically could be under params instead)
	void *data;			// arbitrary user pointer (Sw* generally)
} WashCss;

typedef struct WASH {
	WashHtml *html;
	WashCss *css;
	WashParams *params;
	Pair *param;
	Pair *outvar;
	void *data;			// arbitrary user pointer (Sw* generally)
	struct SWPART *parts;		// Pointer only, do not free this!!
	Pair *cid_index;			// do not free!!
	int flowed;					// Temporary flag during sending whether format flowed is being used
	int warned1, warned2;
	char state[BFSZ];			// to store ref to current accoutn / message
	Wordlist *cids_found;
} Wash;

enum {WASH_FULL_HTML, WASH_STRIP_TO_TEXT, WASH_CID_ONLY, WASH_SIG_CID, WASH_STRIP_FOR_SEND};

void wash_set_imsg(int (*fn)(const char *, ...));
void wash_set_tmpfile(char* (*fn)(void*,char *));
void wash_set_format_url(int (*fn)(void*,char *,SwPart*,char*,char*));
void wash_set_load_mpr_cid_index(int (*fn)(void*,Pair**,char*));
void wash_set_handle_mpr(int (*fn)(void*,Pair**,char*,Pair*,char*));

Wash *wash_new();
int wash_init(Wash *wh);
void wash_free(Wash **wh);


WashHtml *washhtml_new();
WashCss *washcss_new();
void washhtml_free(WashHtml **b);
void washcss_free(WashCss **b);

FILE *wash_fordisplay_html(Wash *wh, FILE *f, int keep_open, int type);
int wash_html_process(Wash *wh, char *data, int len);

int wash_process_fullhtml(void *d, Buffer *buffer, Html *h, FILE*fout, WashParams *params);
int wash_strip_totext(void *d, Buffer *buffer, Html *h, FILE*fout, WashParams *params);
int wash_cid_only(void *d, Buffer *buffer, Html *h, FILE*fout, WashParams *params);
int wash_strip_forsend(void *d, Buffer *buffer, Html *h, FILE *fout, WashParams *params);
int wash_sig_cid(void *d, Buffer *buffer, Html *h, FILE *fout, WashParams *params);


// CSS washing code *** begin ***
int wash_css_write(Css *css, char *str, int len, FILE *fout);
int wash_fordisplay_css(Wash *wh, WashCss **h, FILE *fout, char *data, int len);
int wash_css_process(Wash *wh, WashCss *io, char *data, int len);
int wash_process_fullcss(void *d, Buffer *buffer, Css *h, FILE *fout);
// CSS washing code *** end ***

int wash_mpr_show(Wash *wh, Html *h, FILE *fout, WashParams *params, int check);
int wash_xss_tag_clean(Wash *wh, struct tag *tag);

int wash_text_semiflowed_eol(Wash *wh, Html *h, FILE *fout, WashParams *params);
int wash_text_semiflowed_output(Wash *wh, Html *h, FILE *fout, WashParams *params, char *txt, int len);
