#ifndef __STATIC_HELP__H__
#define __STATIC_HELP__H__

#include <sstream>
#include <string>
#include <vector>

#include "version.h"

using namespace std;

/* This class stores the help screen for logserver. It takes an ILogLines and
 * populates it with all the help lines
 */
class StaticHelp {
public:
	static inline const string NAME = "help";

	static void render(ILogLines* out) {
		Run run("whoami");
		run();
		string me = run.read();
		if (!me.empty()) me = me.substr(0, me.length() - 1);
		out->add_line(help_lines[0]);
		string top = "              ";
		string name = top + " " + me + "'s logserver";
		for (size_t i = 0; i < me.length() + 14; ++i) {
			top += '=';
		}
		out->add_line(top);
		out->add_line(name);
		out->add_line(top);
		out->add_line("");
		out->add_line("");
		out->add_line(help_lines[6]);
		out->add_line("");

		vector<string> quotebox = help_quote();
		size_t i;
		for (i = 0; i < quotebox.size(); ++i) {
			out->add_line(help_lines[8 + i] + quotebox[i]);
		}
		i += 8;
		while (i < help_lines.size()) {
			out->add_line(help_lines[i]);
			++i;
		}
	}

protected:
	static inline const vector<string> help_lines = {
"                              ",
"                ================",
"                 YOUR LOGSERVER",
"                ================",
"",
"",
string(" version: ") + Version::VERSION,
"",
"                                   ",//+----------------+",
"     (ESC goes back)        +--+   ",//|  LOGS ANYONE?  |",
"                            |  |   ",//|     LOGS??     |",
"                            |  |   ",//+----------------+",
"                          --+--+--   /                          ",
"                           /   \\    /                            ",
"                           |   | --/                           ",
"                           \\ - /                             ",
"                            \\_/                                 ",
"        (o)==)              | |                                  ",
"       (o)=====)    -------------------                           ",
"     (o)========)   \\                 /                          ",
"    -------------    \\     |\\ /|     /                          ",
"           |          \\    |/ \\|    /                           ",
"           |           \\     .     /                            ",
"           +------------\\    .    /                             ",
"                         \\   .   /                             ",
"                          \\     /                ",
"                           \\   /           ",
"                            \\ /                             ",
"                             -                         ",
"                            / \\                         ",
"                           |   |                         ",
"                  bizzz---- \\_/                             ",
"",
"",
" Logserver",
" Copyright (C) 2017-2025 Joel Reardon",
"",
" 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 3 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",
" GNU General Public License for more details.",
"",
" You should have received a copy of the GNU General Public License",
" along with this program.  If not, see <https://www.gnu.org/licenses/>.",
"",
"",
"KEYBINDINGS FOR NAVIGATION:",
"       arrows:",
"              Move around in the file. Long lines do not wrap so left and right moves accordingly.",
"",
"       home:  Move to the top of the file.",
"",
"       end:   Move  to one-past the end of the file, which will display streaming data",
"",
"       shift+home:",
"              move left to the start of the line",
"",
"       shift+end:",
"              move right to the end of the line",
"",
"       page-up:",
"              move to the top line visible",
"",
"       page-down:",
"              move to the bottom line visible",
"",
"       colon: accepts a number afterwards, and moves to that line number",
"",
"",
"KEYBINDINGS FOR SEARCHING:",
"       slash: Accepts a keyword afterwards, and adds it as a search term.",
"",
"       backslash:",
"              Accepts a keyword afterwards, and adds it as a reverse search.",
"",
"       caret: Accepts a keyword afterwards, and adds it as a starts with search.",
"",
"       dollar sign:",
"              Accepts a keyword afterwards, and adds it as an ends with search.",
"",
"       tab:   Alternates  among  search  modes.",
"              ALL mode shows all lines and highlights matching keywords.",
"              OR mode (disjunctive) shows lines that match any keyword.",
"              AND mode (conjunctive) shows lines that match all keywords.",
"",
"       shift+left:",
"              move left on the current line to the next matching keyword",
"",
"       shift+right:",
"              move right on the current line to the next matching keyword",
"",
"       shift+up:",
"              In ALL mode, moves up to the next line that matches any keyword.",
"              In OR mode, moves up to the next line that matches",
"              a keyword that is not matched on the current line.",
"              Useful for staying in OR mode but skipping large amounts of the same match.",
"",
"       shift+down:",
"              Same as shift+up but searches downwards.",
"",
"       backspace:",
"              Removes the most-recently added search term.",
"",
"       plus:  Add one more line of context around matching lines.",
"",
"       minus: Remove one line of context around matching lines.",
"",
"",
"KEYBINDINGS FOR LINE OPERATIONS:",
"       octothorpe:",
"              Accepts a string afterwards, and adds the current line and surrounding view",
"              along with that comment to a file in current directory called storytime.txt.",
"",
"       letter e:",
"              Accepts  a  string starting with the current line. Changes to that line are",
"              reflected in the display (but not the original file).",
"",
"       letter b:",
"              Breaks a long line up and inserts the new lines.",
"              This uses a number of heuristics in an attempt to be elegant.",
"              It uses spaces and punctuation to give a ragged-right in text.",
"              It uses ampersands and equals to infer HTTP query strings and breaks on the ampersand.",
"              It uses quotes and braces to infer JSON for pretty printing.",
"              It uses periodic backslash-n to infer escape newlines and breaks on those.",
"",
"       letter B:",
"              Accepts a single character next, and performs the break functionality",
"              described for the letter b using that specific character,",
"              i.e., replaces that character with newlines.",
"",
"       letter i:",
"              Intelligence for lines. Replaces UNIX timestamps with human time.",
"              Looks for sequences of base64 or base16 encoded text based on printable characters after decoding.",
"              Repeated pressing of 'i' softens the heuristics of how much text needs to be printable.",
"",
"       letter d:",
"              If  hit twice in a row, deletes the current line from the display (not from the original file).",
"",
"       asterisk:",
"              Pins the current line. When searching for keywords pinned lines will appear in OR and AND mode despite not matching.",
"",
"       letter s:",
"              Accepts a string afterwards, and writes the current line to the file specified by that string.",
"",
"       letter f:",
"              Follows a link on the current line.",
"              If logserver is given the output of `grep -n`",
"              then each line will link to that file and line number and 'f' will follow it.",
"              If logserver is reading a ctags file, then each line will be a link to that target.",
"       letter m:",
"              Merges the next line to the current line.",
"",
"",
"KEYBINDINGS FOR GLOBAL OPERATIONS AND STACKED VIEWS",
"       letter q:",
"              Quits logserver.",
"",
"       letter n:",
"              Toggle line numbers on and off.",
"",
"       letter c:",
"              Toggle colouring on and off.",
"",
"       letter S:",
"              Accepts a string afterwards, and writes the entire log file to the file specified by that string.",
"              This is useful when data is bring streamed into logserver by program output.",
"",
"       letter h:",
"              Launch the help screen, pushes on the stack.",
"",
"       letter C:",
"              Clears the entire contents of the log. This is useful when streaming in data,",
"              e.g., a device log, and you want the logs relevant to a particular event that is about to be triggered.",
"",
"       exclamation:",
"              Inserts a new pinned dash line at the current position.",
"              Appends it if the current line is one-past the end.",
"              Useful for separating segments of the log, such as the debug log corresponding to",
"              immediately before pressing a button which cause a program crash to mark these events",
"",
"       percent:"
"              In OR and AND mode, applies the current filter and creates a new view with just the matching lines",
"              and puts that on the stack (i.e., some percent of the logs).",
"              In ALL mode, goes up and down from the current position searching  for a pinned like,",
"              such as one created by an exclamation, and pushes a new view on the stack bounded by those",
"              (or the top and bottom if none are found).",
"",
"       less-than:",
"              Moves left on the stack of views",
"",
"       greater-than:",
"              Moves right on the stack of views.",
"",
"       escape:",
"              Pops the top most (right most) view on the stack. Does nothing if there is only one view.",
"",
"       pipe:",
"             Accepts a string afterwards and runs that command, passing the current view as stdin,",
"             and pushing a new view on the stack with the stdout of the command as its contents.",
"             For security purposes the set of commands that can be run is limited to the following:",
"             cat, sort, uniq, ls, grep, cut, tr, sed, awk, fgrep, which, whoami, base64, echo, file, wc, xsel, mplayer.",
"",
"",
"	letter T:",
"               Consider the next key pressed as the tab character, so T-comma can be for CSVs",
"",
"       letter t:",
"               Toggle tab mode, where tab character and column widths are used to align tabular data",
"",
"       numbers 0-9:",
"               In tab mode, toggle suppression of column number. Columns are indexed starting at 1, with number ten as 0",
"",
"",
"",
"             Wanna try it out? Hit 'f' on the next line to see!",
"                                @DEMOTIME",
""	};

	/* choose a random quote for logserver to state */
	static vector<string> help_quote() {
		vector<string> ret;
		int x = rand() % 7;
		if (x == 0) {
			ret.push_back("+----------------+");
			ret.push_back("+  LOGS ANYONE?  +");
			ret.push_back("+     LOGS??     +");
			ret.push_back("+----------------+");
		} else if (x == 1) {
			ret.push_back("+------------------+");
			ret.push_back("+  STREAMING LOGS  +");
			ret.push_back("+  AVAILABLE NOW!  +");
			ret.push_back("+------------------+");
		} else if (x == 2) {
			ret.push_back("+-----------------+");
			ret.push_back("+  LOGS HERE, AT  +");
			ret.push_back("+  YOUR SERVICE!  +");
			ret.push_back("+-----------------+");
		} else if (x == 3) {
			ret.push_back("+-----------------------+");
			ret.push_back("+  PLEASE ALLOW ME TO   +");
			ret.push_back("+  SERVE YOU SOME LOGS! +");
			ret.push_back("+-----------------------+");
		} else if (x == 4) {
			ret.push_back("+-------------------------+");
			ret.push_back("+   AT ONCE, RIGHT AWAY   +");
			ret.push_back("+  MESDAMES ET MESSEURS!  +");
			ret.push_back("+-------------------------+");
		} else if (x == 5) {
			ret.push_back("+--------------------------+");
			ret.push_back("+   REMEMBER, DON'T LOG    +");
			ret.push_back("+  SENSITIVE INFOMRATION!  +");
			ret.push_back("+--------------------------+");
		} else if (x == 6) {
			ret.push_back("+----------------------+");
			ret.push_back("+  ETERNALLY GRATEFUL  +");
			ret.push_back("+  TO SERVE YOU LOGS   +");
			ret.push_back("+----------------------+");
		}
		return ret;
	}
};

#endif  // __STATIC_HELP__H__
