use v6.c;

use Nginx::Config;

unit class Nginx::Config::Actions;

sub get_directive(@directives, Str $name) {
    return @directives.first({ $_{$name}:exists }){$name}.ast;
}

method TOP($/) {
    make Nginx::Config.new(
        :servers($<server>».ast),
        :comment($<comment>».ast),
    );
}

method server($/) {

#   say $<comment>».ast.grep: Nginx::Config::Comment;
    make Nginx::Config::Server.new(
        :names(get_directive($<directive>, 'server_name')),
        :directives($<directive>».ast.grep: Nginx::Config::Directive),
        :comments($<comment>».ast.grep: Nginx::Config::Comment),
    );
}

method directive($/) {
    make $/.values[0].ast;
}

method comment($/) {
    make Nginx::Config::Comment.new(:content($0));
}

method deny($/) {
    make Nginx::Config::Deny.new(
        :rule($<string>.ast)
        :comment($<comment> ?? $<comment>[0].Str !! Empty)
    );
}

method allow($/) {
    make Nginx::Config::Allow.new(
        :rule($<string>.ast)
        :comment($<comment> ?? $<comment>[0].Str !! Empty)
    );
}

method server_name($/) {
    make $<domain>».Str;
}

method root($/) {
    make Nginx::Config::Root.new(:path($<path>.ast));
}

method listen($/) {
    make Nginx::Config::Listen.new(
        :host($<domain>.ast),
        :port($<port>.ast),
        :flag($<string>.ast),
    );
}

method error_page($/) {
    make Nginx::Config::ErrorPage.new(|$/);
}

method include($/) {
    make Nginx::Config.class-for-stanza($<path>.ast);
}

method set($/) {
    make Nginx::Config::Set.new(:variable($<variable>.ast), :value($<string>.ast));
}

method location($/) {
    make Nginx::Config::Location.new(
        :op($<op> ?? $<op>.ast !! Empty),
        :path($<string>.ast),
        :directives($<directive> ?? $<directive>».ast !! Empty),
    );
}

method alias($/) {
    make Nginx::Config::Alias.new(:target($<string>.ast));
}

method return-uri($/) {
    make Nginx::Config::Return.new(
        :value($<uri>.ast),
        :http_status($<status> ?? $<status>.ast !! Empty),
    );
}

method rewrite($/) {
    make Nginx::Config::Rewrite.new(
        :regex($<expression>.ast),
        :replacement($<uri>.ast),
        :redirect($0),
    );
}

method if($/) {
    make Nginx::Config::If.new(
        :variable($<variable>.ast),
        :op($<op>.ast),
        :value($<string>.ast),
        :directives($<directive> ?? $<directive>».ast !! Empty),
    );
}

method ssl_certificate($/) {
    make Nginx::Config::SslCert.new(:certificate_path($<uri>.ast));
}

method ssl_certificate_key($/) {
    make Nginx::Config::SslCertKey.new(:certificate_path($<uri>.ast));
}

method proxy_set_header($/) {
    make Nginx::Config::ProxySetHeader.new(
        :command($<string>.ast),
        :variable($<variable>.ast),
    );
}

method proxy_pass($/) {
    make Nginx::Config::ProxyPass.new(
        :address($<uri>.ast)
        :comment($<comment> ?? $<comment>[0].Str !! Empty),
    );
}

method proxy_redirect($/) {
    make Nginx::Config::ProxyRedirect.new(
        :path($<uri>».ast),
    );
}

method try_files($/) {
    make Nginx::Config::TryFiles.new(
        :variable($<variable>.ast),
        :uri($<uri>.ast),
        :status($<status> ?? $<status>.ast !! Empty),
    );
}

method internal($/) {
    make Nginx::Config::Internal.new(
        :word($0),
    )
}

method default_type($/) {
    make Nginx::Config::DefaultType.new(
        :default_type($<uri>.ast),
    );
}

method charset($/) {
    make Nginx::Config::CharSet.new(
        :character_set($<string>.ast)
    );
}

method index($/) {
    make Nginx::Config::Index.new(
        :path($<uri>».ast),
    );
}

method add_header($/) {
    make Nginx::Config::Add_Header.new(
        :header_values($<string_with_quotes>».ast),
    );
}

method add_trailer($/) {
    make Nginx::Config::Add_Trailer.new(
        :trailer_values($<string>».ast),
    );
}

method expires($/) {
    make Nginx::Config::Expires.new(
        :expire_values($<string>».ast),
    );
}

method path($/) {
    make $/.Str;
}

method domain($/) {
    make $/.Str;
}

method port($/) {
    make $/.Str;
}

method uri($/) {
    make $/.Str;
}

method status($/) {
    make $/.Str;
}

method variable($/) {
    make $/.Str;
}

method expression($/) {
    make $/.Str;
}

method string($/) {
    make $0.Str;
}

method string_with_quotes($/) {
    make $0.Str;
}

method op($/) {
    make $/.Str;
}

# vim: ft=perl6
