// File: /workspace/github_cpp_makefile_star2_O3/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, %rbx
movq %rcx, %r14
movq %rdx, %r15
movq %rsi, %r12
movq %rdi, %r13
movq %rdx, %rdi
movl $0x2e, %esi
xorl %edx, %edx
callq 0x8680
cmpq $-0x1, %rax
je 0x16e75
movq %r13, %rdi
movq %r15, %rsi
movq %rbx, %rdx
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x8dbc
movq %r14, -0x68(%rbp)
movq %rbx, -0x58(%rbp)
movq (%r15), %rax
movq 0x8(%r15), %rcx
movb -0x1(%rax,%rcx), %r14b
leaq -0xc8(%rbp), %rbx
movq %rbx, %rdi
movq %r12, -0x98(%rbp)
movq %r12, %rsi
movq %r15, %rdx
callq 0x17c65
movq %r13, -0x70(%rbp)
movq %r13, %rdi
movq %rbx, %rsi
callq 0x17e3e
movq %rax, %rbx
movq %r15, -0x60(%rbp)
movq -0x70(%rbp), %r15
leaq 0x8(%r15), %rax
cmpq %rax, %rbx
je 0x16eea
cmpq $0x0, 0x50(%rbx)
je 0x1722f
movq %rbx, %rdi
addq $0x40, %rdi
movq -0x68(%rbp), %rsi
movq -0x58(%rbp), %rdx
callq *0x58(%rbx)
jmp 0x171f9
leaq -0x40(%rbp), %rax
movq %rax, -0x10(%rax)
movq -0xc8(%rbp), %rsi
movq -0xc0(%rbp), %rdx
addq %rsi, %rdx
leaq -0x50(%rbp), %rdi
callq 0xb088
cmpb $0x2f, %r14b
leaq 0xdcc8(%rip), %rax      # 0x24bdf
leaq 0xdcc0(%rip), %rsi      # 0x24bde
cmoveq %rax, %rsi
leaq -0x50(%rbp), %rdi
callq 0x88d0
leaq -0x50(%rbp), %rsi
movq %r15, %rdi
callq 0x17e3e
movq %rax, %r14
movq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rax
cmpq %rax, %rdi
je 0x16f53
movq -0x40(%rbp), %rsi
incq %rsi
callq 0x8520
cmpq %rbx, %r14
movq -0x60(%rbp), %r15
je 0x16f7e
cmpq $0x0, 0x50(%r14)
je 0x1722f
movq %r14, %rdi
addq $0x40, %rdi
movq -0x68(%rbp), %rsi
movq -0x58(%rbp), %rdx
callq *0x58(%r14)
movq -0x60(%rbp), %r15
movq %r15, %rdi
movl $0x2f, %esi
movq $-0x1, %rdx
callq 0x8910
cmpq $-0x1, %rax
je 0x17131
movq %rax, %r14
movq -0x70(%rbp), %rax
leaq 0x30(%rax), %rcx
movq %rcx, -0xa8(%rbp)
addq $0x38, %rax
movq %rax, -0xa0(%rbp)
movl $0x1, %r12d
leaq -0x90(%rbp), %r13
leaq -0x50(%rbp), %rbx
leaq 0x1(%r14), %rcx
movq %r13, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x8550
movq -0x98(%rbp), %rax
movq (%rax), %rcx
movq 0x8(%rax), %r8
movq %r13, %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 0x17019
movq %rdx, -0x50(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x40(%rbp)
jmp 0x1701f
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 -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
cmpq %rax, %rdi
je 0x17052
movq -0x80(%rbp), %rsi
incq %rsi
callq 0x8520
testq %r12, %r12
je 0x17092
movq %r12, %r13
negq %r13
movl $0x1, %r15d
movq %rbx, %rdi
movl $0x2a, %esi
callq 0x8480
cmpq %r15, %r12
jbe 0x17082
movq %rbx, %rdi
movl $0x2f, %esi
callq 0x8480
leaq (%r15,%r13), %rax
incq %rax
incq %r15
cmpq $0x1, %rax
jne 0x17063
movq -0xa8(%rbp), %rdi
movq %rbx, %rsi
callq 0x17e3e
cmpq -0xa0(%rbp), %rax
je 0x170cf
cmpq $0x0, 0x50(%rax)
je 0x1722a
movq %rax, %rdi
addq $0x40, %rdi
movq -0x68(%rbp), %rsi
movq -0x58(%rbp), %rdx
callq *0x58(%rax)
xorl %r15d, %r15d
xorl %r13d, %r13d
jmp 0x170dd
incq %r12
testq %r14, %r14
setne %r15b
sete %r13b
movq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rax
cmpq %rax, %rdi
je 0x170f6
movq -0x40(%rbp), %rsi
incq %rsi
callq 0x8520
testb %r15b, %r15b
je 0x17128
decq %r14
movq -0x60(%rbp), %r15
movq %r15, %rdi
movl $0x2f, %esi
movq %r14, %rdx
callq 0x8910
movq %rax, %r14
cmpq $-0x1, %rax
leaq -0x90(%rbp), %r13
jne 0x16fca
jmp 0x17131
testb %r13b, %r13b
je 0x171f9
movq -0x70(%rbp), %rdi
addq $0x60, %rdi
movq -0x98(%rbp), %rsi
callq 0x17d2a
leaq -0x90(%rbp), %rdi
movq %rax, %rsi
callq 0x17daa
movq -0x90(%rbp), %rbx
movq -0x88(%rbp), %r13
cmpq %r13, %rbx
movq -0x60(%rbp), %rax
je 0x171c8
addq $0x20, %rbx
leaq -0x50(%rbp), %r14
leaq -0x20(%rbx), %rcx
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 0x183f1
movl %eax, %r12d
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x171af
movq -0x40(%rbp), %rsi
subq %rdi, %rsi
callq 0x8520
testb %r12b, %r12b
jne 0x171d8
leaq 0x40(%rbx), %rax
addq $0x20, %rbx
cmpq %r13, %rbx
movq %rax, %rbx
movq -0x60(%rbp), %rax
jne 0x17173
movq -0x58(%rbp), %rdi
movl $0x194, %esi            # imm = 0x194
callq 0xa54e
jmp 0x171ed
cmpq $0x0, 0x10(%rbx)
je 0x17234
movq %rbx, %rdi
movq -0x68(%rbp), %rsi
movq -0x58(%rbp), %rdx
callq *0x18(%rbx)
leaq -0x90(%rbp), %rdi
callq 0x134ba
leaq -0xb8(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x17218
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 0x1723b
movq %rax, %rbx
jmp 0x17264
jmp 0x17292
jmp 0x17292
jmp 0x1728b
jmp 0x1728b
jmp 0x17292
jmp 0x1728b
movq %rax, %rbx
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x17264
movq -0x40(%rbp), %rsi
subq %rdi, %rsi
callq 0x8520
leaq -0x90(%rbp), %rdi
callq 0x134ba
jmp 0x172ae
movq %rax, %rbx
movq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
cmpq %rax, %rdi
je 0x172ae
movq -0x80(%rbp), %rsi
jmp 0x172a6
movq %rax, %rbx
jmp 0x172ae
jmp 0x17292
movq %rax, %rbx
movq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rax
cmpq %rax, %rdi
je 0x172ae
movq -0x40(%rbp), %rsi
incq %rsi
callq 0x8520
leaq -0xb8(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x172cd
movq -0xb8(%rbp), %rsi
incq %rsi
callq 0x8520
movq %rbx, %rdi
callq 0x8830
nop