##! Internal functions and types used by the file analysis framework.

module Files;

%%{
#include "zeek/file_analysis/Manager.h"
#include "zeek/file_analysis/File.h"
#include "zeek/Reporter.h"
%%}

type AnalyzerArgs: record;

## :zeek:see:`Files::set_timeout_interval`.
function Files::__set_timeout_interval%(file_id: string, t: interval%): bool
	%{
	bool result = zeek::file_mgr->SetTimeoutInterval(file_id->CheckString(), t);
	return zeek::val_mgr->Bool(result);
	%}

## :zeek:see:`Files::enable_reassembly`.
function Files::__enable_reassembly%(file_id: string%): bool
	%{
	bool result = zeek::file_mgr->EnableReassembly(file_id->CheckString());
	return zeek::val_mgr->Bool(result);
	%}

## :zeek:see:`Files::disable_reassembly`.
function Files::__disable_reassembly%(file_id: string%): bool
	%{
	bool result = zeek::file_mgr->DisableReassembly(file_id->CheckString());
	return zeek::val_mgr->Bool(result);
	%}

## :zeek:see:`Files::set_reassembly_buffer_size`.
function Files::__set_reassembly_buffer%(file_id: string, max: count%): bool
	%{
	bool result = zeek::file_mgr->SetReassemblyBuffer(file_id->CheckString(), max);
	return zeek::val_mgr->Bool(result);
	%}

## :zeek:see:`Files::enable_analyzer`.
function Files::__enable_analyzer%(tag: Files::Tag%) : bool
	%{
	auto c = zeek::file_mgr->Lookup(tag->AsEnumVal(), false);

	if ( ! c )
		return zeek::val_mgr->False();

	c->SetEnabled(true);
	return zeek::val_mgr->True();
	%}

## :zeek:see:`Files::disable_analyzer`.
function Files::__disable_analyzer%(tag: Files::Tag%) : bool
	%{
	auto c = zeek::file_mgr->Lookup(tag->AsEnumVal(), false);

	if ( ! c )
		return zeek::val_mgr->False();

	c->SetEnabled(false);
	return zeek::val_mgr->True();
	%}

## :zeek:see:`Files::analyzer_enabled`.
function Files::__analyzer_enabled%(tag: Files::Tag%) : bool
	%{
	auto c = zeek::file_mgr->Lookup(tag->AsEnumVal());
	return zeek::val_mgr->Bool(c && c->Enabled());
	%}

## :zeek:see:`Files::add_analyzer`.
function Files::__add_analyzer%(file_id: string, tag: Files::Tag, args: any%): bool
	%{
	using zeek::BifType::Record::Files::AnalyzerArgs;
	auto rv = args->AsRecordVal()->CoerceTo(AnalyzerArgs);
	bool result = zeek::file_mgr->AddAnalyzer(
	     file_id->CheckString(),
	     zeek::file_mgr->GetComponentTag(tag),
	     std::move(rv));
	return zeek::val_mgr->Bool(result);
	%}

## :zeek:see:`Files::remove_analyzer`.
function Files::__remove_analyzer%(file_id: string, tag: Files::Tag, args: any%): bool
	%{
	using zeek::BifType::Record::Files::AnalyzerArgs;
	auto rv = args->AsRecordVal()->CoerceTo(AnalyzerArgs);
	bool result = zeek::file_mgr->RemoveAnalyzer(
		file_id->CheckString(),
		zeek::file_mgr->GetComponentTag(tag),
		std::move(rv));
	return zeek::val_mgr->Bool(result);
	%}

## :zeek:see:`Files::stop`.
function Files::__stop%(file_id: string%): bool
	%{
	bool result = zeek::file_mgr->IgnoreFile(file_id->CheckString());
	return zeek::val_mgr->Bool(result);
	%}

## :zeek:see:`Files::analyzer_name`.
function Files::__analyzer_name%(tag: Files::Tag%) : string
	%{
	return zeek::file_mgr->GetComponentNameVal(zeek::IntrusivePtr{zeek::NewRef{}, tag->AsEnumVal()});
	%}

## :zeek:see:`Files::file_exists`.
function Files::__file_exists%(fuid: string%): bool
	%{
	if ( zeek::file_mgr->LookupFile(fuid->CheckString()) != nullptr )
		return zeek::val_mgr->True();
	else
		return zeek::val_mgr->False();
	%}

## :zeek:see:`Files::lookup_file`.
function Files::__lookup_file%(fuid: string%): fa_file
	%{
	auto f = zeek::file_mgr->LookupFile(fuid->CheckString());
	if ( f != nullptr )
		return f->ToVal();

	reporter->Error("file ID %s not a known file", fuid->CheckString());
	return nullptr;
	%}

module GLOBAL;

## For use within a :zeek:see:`get_file_handle` handler to set a unique
## identifier to associate with the current input to the file analysis
## framework.  Using an empty string for the handle signifies that the
## input will be ignored/discarded.
##
## handle: A string that uniquely identifies a file.
##
## .. zeek:see:: get_file_handle
function set_file_handle%(handle: string%): any
	%{
	auto bytes = reinterpret_cast<const char*>(handle->Bytes());
	auto h = std::string(bytes, handle->Len());
	zeek::file_mgr->SetHandle(h);
	return nullptr;
	%}
