// File: /workspace/github_cpp_makefile_star2_O1/trisolaris233[P]httpc/src/http_router.hpp
// Function: httpc::HttpRouter::Route(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, httpc::Request&, httpc::Response&)
void Route(
            const std::string& http_method,
            const std::string& route_directory, 
            Request& request, 
            Response& response
        ) {
            
            if (route_directory.find('.') != std::string::npos) {
                // std::cout << "Render local file" << std::endl;
                this->InvokeLocalFileRenderer(route_directory, response);
                // response.RenderFromStaticFile(this->server_->GetDocumentRoot() + route_directory);
                return;
            }

            bool end_with_slash = (route_directory.back() == '/');
            // try to search directory
            std::string key(http_method + route_directory);
            auto res_itr = directly_router_map_.find(key);
            if (res_itr != directly_router_map_.end()) {
                return res_itr->second(request, response);
            } 


            res_itr = directly_router_map_.find(key + ((end_with_slash) ? "?" : "/?"));            
            if (res_itr != directly_router_map_.end()) {
                res_itr->second(request, response);
            }

            // try fezzy match
            std::size_t num_of_slash{ 1 };
            for (
                auto pos_of_slash = route_directory.rfind('/');
                pos_of_slash != std::string::npos;
                pos_of_slash = route_directory.rfind('/', pos_of_slash - 1)
            ) {
                std::string tmp(http_method + route_directory.substr(0, pos_of_slash + 1));
                for (auto i = 0; i < num_of_slash; ++i) {
                    tmp.push_back('*');
                    if (i + 1 < num_of_slash) {
                        tmp.push_back('/');
                    }
                }
                
                auto wildcard_itr = wildcard_router_map_.find(tmp);
                if (wildcard_itr != wildcard_router_map_.end()) {
                    return wildcard_itr->second(request, response);
                }

                num_of_slash++;
                
                if (pos_of_slash == 0) 
                    break;
            }
            
            // try regex match
            auto method_regex_list = regex_router_map_[http_method];
            
            for (const auto& reg : method_regex_list) {
                if (std::regex_match(route_directory, reg.first)) {
                    return reg.second(request, response);
                }   
            }

            response.SetDefault(HTTPStatusCodeEnum::kNotFound);
        }

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %r8, %r15
movq %rcx, %r13
movq %rdx, %r14
movq %rsi, %rbx
movq %rdi, %r12
movq %rdx, %rdi
movl $0x2e, %esi
xorl %edx, %edx
callq 0x8680
cmpq $-0x1, %rax
je 0x171df
movq %r12, %rdi
movq %r14, %rsi
movq %r15, %rdx
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x8e0c
movq (%r14), %rax
movq 0x8(%r14), %rcx
movb -0x1(%rax,%rcx), %al
movb %al, -0x68(%rbp)
movq %rbx, %rsi
leaq -0xc8(%rbp), %rbx
movq %rbx, %rdi
movq %rsi, -0xa0(%rbp)
movq %r14, -0x58(%rbp)
movq %r14, %rdx
callq 0x180e1
movq %r12, -0x60(%rbp)
movq %r12, %rdi
movq %rbx, %rsi
callq 0x182ba
movq -0x60(%rbp), %rbx
leaq 0x8(%rbx), %r14
cmpq %r14, %rax
je 0x17249
cmpq $0x0, 0x50(%rax)
je 0x175ad
movq %rax, %rdi
addq $0x40, %rdi
movq %r13, %rsi
movq %r15, %rdx
callq *0x58(%rax)
jmp 0x17572
leaq -0x40(%rbp), %rax
movq %rax, -0x10(%rax)
movq -0xc8(%rbp), %rsi
movq -0xc0(%rbp), %rdx
addq %rsi, %rdx
leaq -0x50(%rbp), %rdi
callq 0xb0fe
cmpb $0x2f, -0x68(%rbp)
leaq 0xd969(%rip), %rax      # 0x24bdf
leaq 0xd961(%rip), %rsi      # 0x24bde
cmoveq %rax, %rsi
leaq -0x50(%rbp), %rdi
callq 0x88d0
leaq -0x50(%rbp), %rsi
movq %rbx, %rdi
callq 0x182ba
movq %rax, %rbx
movq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rax
cmpq %rax, %rdi
je 0x172b2
movq -0x40(%rbp), %rsi
incq %rsi
callq 0x8520
cmpq %r14, %rbx
je 0x172d2
cmpq $0x0, 0x50(%rbx)
je 0x175ad
movq %rbx, %rdi
addq $0x40, %rdi
movq %r13, %rsi
movq %r15, %rdx
callq *0x58(%rbx)
movq -0x58(%rbp), %rdi
movl $0x2f, %esi
movq $-0x1, %rdx
callq 0x8910
cmpq $-0x1, %rax
movq %r13, -0x98(%rbp)
je 0x174ad
movq %rax, %r14
movq %r15, -0x90(%rbp)
movq -0x60(%rbp), %rax
leaq 0x30(%rax), %rcx
movq %rcx, -0x68(%rbp)
addq $0x38, %rax
movq %rax, -0xa8(%rbp)
movl $0x1, %r13d
leaq -0x88(%rbp), %r12
leaq -0x50(%rbp), %rbx
movq -0x58(%rbp), %r15
leaq 0x1(%r14), %rcx
movq %r12, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x8550
movq -0xa0(%rbp), %rax
movq (%rax), %rcx
movq 0x8(%rax), %r8
movq %r12, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x85a0
leaq -0x40(%rbp), %rsi
movq %rsi, -0x50(%rbp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x1737d
movq %rdx, -0x50(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x40(%rbp)
jmp 0x17383
movups (%rcx), %xmm0
movups %xmm0, (%rsi)
movq 0x8(%rax), %rdx
movq %rdx, -0x48(%rbp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
movq -0x88(%rbp), %rdi
leaq -0x78(%rbp), %rax
cmpq %rax, %rdi
je 0x173b6
movq -0x78(%rbp), %rsi
incq %rsi
callq 0x8520
testq %r13, %r13
je 0x173f6
movq %r13, %r12
negq %r12
movl $0x1, %r15d
movq %rbx, %rdi
movl $0x2a, %esi
callq 0x8480
cmpq %r15, %r13
jbe 0x173e6
movq %rbx, %rdi
movl $0x2f, %esi
callq 0x8480
leaq (%r12,%r15), %rax
incq %rax
incq %r15
cmpq $0x1, %rax
jne 0x173c7
movq -0x68(%rbp), %rdi
movq %rbx, %rsi
callq 0x182ba
cmpq -0xa8(%rbp), %rax
je 0x17439
cmpq $0x0, 0x50(%rax)
je 0x175a3
movq %rax, %rdi
addq $0x40, %rdi
movq -0x98(%rbp), %rsi
movq -0x90(%rbp), %rdx
callq *0x58(%rax)
movl $0x1, %r12d
xorl %r15d, %r15d
jmp 0x1744d
incq %r13
xorl %r12d, %r12d
testq %r14, %r14
setne %r15b
sete %r12b
addl %r12d, %r12d
movq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rax
cmpq %rax, %rdi
je 0x17466
movq -0x40(%rbp), %rsi
incq %rsi
callq 0x8520
testb %r15b, %r15b
je 0x1749c
decq %r14
movq -0x58(%rbp), %r15
movq %r15, %rdi
movl $0x2f, %esi
movq %r14, %rdx
callq 0x8910
movq %rax, %r14
cmpq $-0x1, %rax
leaq -0x88(%rbp), %r12
jne 0x1732e
movl $0x2, %r12d
cmpl $0x2, %r12d
movq -0x90(%rbp), %r15
jne 0x17572
movq -0x60(%rbp), %rdi
addq $0x60, %rdi
movq -0xa0(%rbp), %rsi
callq 0x181a6
leaq -0x88(%rbp), %rdi
movq %rax, %rsi
callq 0x18226
movq -0x88(%rbp), %rbx
movq -0x80(%rbp), %r13
cmpq %r13, %rbx
je 0x17559
addq $0x20, %rbx
leaq -0x50(%rbp), %r14
leaq -0x20(%rbx), %rcx
movq -0x58(%rbp), %rax
movq (%rax), %rdi
movq 0x8(%rax), %rsi
addq %rdi, %rsi
xorps %xmm0, %xmm0
movaps %xmm0, -0x40(%rbp)
movaps %xmm0, -0x50(%rbp)
movq %r14, %rdx
xorl %r8d, %r8d
callq 0x18877
movl %eax, %r12d
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x17528
movq -0x40(%rbp), %rsi
subq %rdi, %rsi
callq 0x8520
testb %r12b, %r12b
je 0x17549
cmpq $0x0, 0x10(%rbx)
je 0x175a8
movq %rbx, %rdi
movq -0x98(%rbp), %rsi
movq %r15, %rdx
callq *0x18(%rbx)
testb %r12b, %r12b
jne 0x17566
leaq 0x40(%rbx), %rax
addq $0x20, %rbx
cmpq %r13, %rbx
movq %rax, %rbx
jne 0x174e8
movq %r15, %rdi
movl $0x194, %esi            # imm = 0x194
callq 0xa5ba
leaq -0x88(%rbp), %rdi
callq 0x13770
leaq -0xb8(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x17591
movq -0xb8(%rbp), %rsi
incq %rsi
callq 0x8520
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x8220
callq 0x8220
callq 0x8220
jmp 0x175be
jmp 0x1760d
jmp 0x1760d
jmp 0x17606
jmp 0x17606
jmp 0x175be
movq %rax, %rbx
jmp 0x175df
jmp 0x1760d
jmp 0x17606
movq %rax, %rbx
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x175df
movq -0x40(%rbp), %rsi
subq %rdi, %rsi
callq 0x8520
leaq -0x88(%rbp), %rdi
callq 0x13770
jmp 0x17629
movq %rax, %rbx
movq -0x88(%rbp), %rdi
leaq -0x78(%rbp), %rax
cmpq %rax, %rdi
je 0x17629
movq -0x78(%rbp), %rsi
jmp 0x17621
movq %rax, %rbx
jmp 0x17629
jmp 0x1760d
movq %rax, %rbx
movq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rax
cmpq %rax, %rdi
je 0x17629
movq -0x40(%rbp), %rsi
incq %rsi
callq 0x8520
leaq -0xb8(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x17648
movq -0xb8(%rbp), %rsi
incq %rsi
callq 0x8520
movq %rbx, %rdi
callq 0x8830