// File: /workspace/github_cpp_makefile_star2_O2/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
pushq $0x2e
popq %rsi
movq %rdx, %rdi
xorl %edx, %edx
callq 0x86b0
cmpq $-0x1, %rax
je 0x1477b
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 0x8bfc
movq %r14, -0x30(%rbp)
movq %rbx, -0x38(%rbp)
movq (%r15), %rax
movq 0x8(%r15), %rcx
movb -0x1(%rax,%rcx), %r14b
leaq -0xa8(%rbp), %rbx
movq %rbx, %rdi
movq %r12, -0x48(%rbp)
movq %r12, %rsi
movq %r15, %rdx
callq 0x153c0
movq %r13, -0x40(%rbp)
movq %r13, %rdi
movq %rbx, %rsi
callq 0x1554e
movq %rax, %rbx
movq -0x40(%rbp), %r12
leaq 0x8(%r12), %rax
cmpq %rax, %rbx
je 0x147e1
addq $0x40, %rbx
movq %rbx, %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
callq 0x153f8
jmp 0x149cd
cmpb $0x2f, %r14b
leaq 0xd3f3(%rip), %rax      # 0x21bdf
leaq 0xd3eb(%rip), %rdx      # 0x21bde
cmoveq %rax, %rdx
leaq -0x78(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x1540e
leaq -0x78(%rbp), %rsi
movq %r12, %rdi
callq 0x1554e
movq %rax, %r14
leaq -0x78(%rbp), %rdi
callq 0x8280
cmpq %rbx, %r14
je 0x14838
addq $0x40, %r14
movq %r14, %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
callq 0x153f8
pushq $0x2f
popq %rsi
pushq $-0x1
popq %rdx
movq %r15, %rdi
callq 0x8950
movq %rax, %rdx
movq -0x40(%rbp), %rax
leaq 0x30(%rax), %rcx
movq %rcx, -0x88(%rbp)
addq $0x38, %rax
movq %rax, -0x80(%rbp)
movq %rdx, %rax
pushq $0x1
popq %r13
leaq -0xc8(%rbp), %r14
leaq -0x78(%rbp), %rbx
pushq $0x2a
popq %r12
movq %r15, -0x50(%rbp)
cmpq $-0x1, %rax
je 0x14959
movq %rax, -0x58(%rbp)
leaq 0x1(%rax), %rcx
movq %r14, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x8580
movq %rbx, %rdi
movq -0x48(%rbp), %rsi
movq %r14, %rdx
callq 0x15446
movq %r14, %rdi
callq 0x8280
movq %r13, %r15
negq %r15
pushq $0x1
popq %r14
leaq (%r15,%r14), %rax
cmpq $0x1, %rax
je 0x148e4
movq %rbx, %rdi
movl %r12d, %esi
callq 0x84a0
cmpq %r14, %r13
jbe 0x148df
movq %rbx, %rdi
pushq $0x2f
popq %rsi
callq 0x84a0
incq %r14
jmp 0x148ba
movq -0x88(%rbp), %rdi
movq %rbx, %rsi
callq 0x1554e
cmpq -0x80(%rbp), %rax
je 0x14915
addq $0x40, %rax
movq %rax, %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
callq 0x153f8
xorl %r14d, %r14d
xorl %r15d, %r15d
jmp 0x14925
incq %r13
cmpq $0x0, -0x58(%rbp)
setne %r14b
sete %r15b
movq %rbx, %rdi
callq 0x8280
testb %r14b, %r14b
je 0x14954
movq -0x58(%rbp), %rdx
decq %rdx
movq -0x50(%rbp), %r15
movq %r15, %rdi
pushq $0x2f
popq %rsi
callq 0x8950
leaq -0xc8(%rbp), %r14
jmp 0x1487a
testb %r15b, %r15b
je 0x149cd
movq -0x40(%rbp), %rdi
addq $0x60, %rdi
movq -0x48(%rbp), %rsi
callq 0x15474
leaq -0x78(%rbp), %rdi
movq %rax, %rsi
callq 0x154de
movq -0x78(%rbp), %rbx
movq -0x70(%rbp), %r14
movq -0x38(%rbp), %r15
movq -0x30(%rbp), %r12
cmpq %r14, %rbx
je 0x149a3
movq -0x50(%rbp), %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x15531
testb %al, %al
jne 0x149b2
addq $0x40, %rbx
jmp 0x14986
movq %r15, %rdi
movl $0x194, %esi            # imm = 0x194
callq 0x9b8a
jmp 0x149c4
addq $0x20, %rbx
movq %rbx, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x153f8
leaq -0x78(%rbp), %rdi
callq 0x114ec
leaq -0xa8(%rbp), %rdi
callq 0x8280
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x149f7
jmp 0x149f7
jmp 0x14a18
jmp 0x14a05
jmp 0x14a05
jmp 0x14a05
movq %rax, %rbx
leaq -0x78(%rbp), %rdi
callq 0x114ec
jmp 0x14a24
movq %rax, %rbx
jmp 0x14a24
movq %rax, %rbx
leaq -0xc8(%rbp), %rdi
jmp 0x14a1f
jmp 0x14a18
movq %rax, %rbx
leaq -0x78(%rbp), %rdi
callq 0x8280
leaq -0xa8(%rbp), %rdi
callq 0x8280
movq %rbx, %rdi
callq 0x8850