/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* Copyright (c) 2024-2025 Brett Sheffield <bacs@librecast.net> */

%{
#include <agent.h>
#include <key.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <state.h>
#include <y.tab.h>

void yyerror(state_t *state, const char *str);
int yylex(void);
int yywrap(void);
int reqs = 0;

%}
%parse-param { state_t *state }
%union
{
	int ival;
	char *sval;
}
%token <sval> AUTH_KEY
%token <sval> CHANNEL
%token <sval> CHROOT
%token <sval> COMMAND
%token <sval> COMMENT
%token <sval> TOK_DEBUG
%token <sval> DBLQUOTEDSTRING
%token <sval> DIRECTORY
%token <sval> ENABLE
%token <sval> JOIN
%token <sval> LOGFILE
%token <sval> NOENABLE
%token <sval> NOJOIN
%token <sval> NUMBER
%token <sval> ONSTART
%token <sval> RELOAD
%token <sval> RESTART
%token <sval> SEED
%token <sval> STATUS
%token <sval> STATUS_COMMAND
%token <sval> STDERR
%token <sval> STDIN
%token <sval> STDOUT
%token <sval> STRING
%token <sval> TRY

%%

globals:
        /* empty */
        | globals global
        ;

global:
	COMMENT { /* skip comment */ }
	|
	AUTH_KEY STRING {
		if (state_authkey_set(state, $2) == -1) YYABORT;
	}
	|
	CHANNEL STRING {
		if (state_push_channel(state, $2) == -1) YYABORT;
	}
	|
	CHROOT {
		if (state->chan_head) state->chan_head->flags |= CHAN_CHROOT;
		else state->defaults.flags |= CHAN_CHROOT;
	}
	|
	COMMAND STRING {
		if (state_push_command(state, $2, 0) == -1) YYABORT;
	}
	|
	TOK_DEBUG { state->flag |= STATE_DEBUG; }
	|
	TRY STRING {
		if (state_push_command(state, $2, CMD_TRY) == -1) YYABORT;
	}
	|
	DIRECTORY STRING {
		if (state_dir_set(state, $2) == -1) YYABORT;
	}
	|
	LOGFILE STRING {
		if (state_logfile_set(state, $2) == -1) YYABORT;
	}
	|
	ENABLE {
		if (state->chan_head) state->chan_head->flags |= CHAN_ENABLE;
		else state->defaults.flags |= CHAN_ENABLE;
	}
	|
	NOENABLE {
		if (state->chan_head) state->chan_head->flags &= ~CHAN_ENABLE;
		else state->defaults.flags &= ~CHAN_ENABLE;
	}
	|
	JOIN {
		if (state->chan_head) state->chan_head->flags |= CHAN_JOIN;
		else state->defaults.flags |= CHAN_JOIN;
	}
	|
	NOJOIN {
		if (state->chan_head) state->chan_head->flags &= ~CHAN_JOIN;
		else state->defaults.flags &= ~CHAN_JOIN;
	}
	|
	ONSTART {
		if (state->chan_head) state->chan_head->flags |= CHAN_ONSTART;
		else state->defaults.flags |= CHAN_ONSTART;
	}
	|
	RELOAD {
		if (state->chan_head) state->chan_head->flags |= CHAN_RELOAD;
		else state->defaults.flags |= CHAN_RELOAD;
	}
	|
	RESTART {
		if (state->chan_head) state->chan_head->flags |= CHAN_RESTART;
		else state->defaults.flags |= CHAN_RESTART;
	}
	|
	SEED STRING {
		if (state_seed_set(state, $2) == -1) YYABORT;
	}
	|
	STATUS STRING {
		if (state_status_set(state, $2) == -1) YYABORT;
	}
	|
	STATUS_COMMAND STRING {
		if (state_statuscmd_set(state, $2) == -1) YYABORT;
	}
	|
	STDOUT STRING {
		if (state_stdout_set(state, $2) == -1) YYABORT;
	}
	|
	STDIN STRING {
		if (state_stdin_set(state, $2) == -1) YYABORT;
	}
	|
	STDERR STRING {
		if (state_stderr_set(state, $2) == -1) YYABORT;
	}
	;
%%
void yyerror(state_t *state, const char *str)
{
	(void) state;
	fprintf(stderr,"%s in rcfile %s, error on line %i\n", str, state->rcfile, lineno);
}

int yywrap(void)
{
	return 1;
}
