// File: TwilioDevEd[P]twilio_cpp_demo/src/twilio.cc
// Function: twilio::Twilio::send_message(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&, 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>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool)
bool Twilio::send_message(
        std::string const& to_number,
        std::string const& from_number,
        std::string const& message_body,
        std::string& response,
        std::string const& picture_url,
        bool verbose)
{
        std::stringstream response_stream;
        std::u16string converted_message_body;

        // Assume UTF-8 input, convert to UCS-2 to check size
        // See: https://www.twilio.com/docs/api/rest/sending-messages for
        // information on Twilio body size limits.
        try {
                converted_message_body = utf8_to_ucs2(message_body);
        } catch(const std::range_error& e) {
                response = e.what();
                return false;
        }

        if (converted_message_body.size() > 1600) {
                response_stream << "Message body must have 1600 or fewer"
                        << " characters. Cannot send message with "
                        << converted_message_body.size() << " characters.";
                response = response_stream.str();
                return false;
        }

        CURL *curl;
        curl_global_init(CURL_GLOBAL_ALL);
        curl = curl_easy_init();

        // Percent encode special characters
        char *message_body_escaped = curl_easy_escape(
                curl, 
                message_body.c_str(), 
                0
        );


        std::stringstream url;
        std::string url_string;
        url << "https://api.twilio.com/2010-04-01/Accounts/" << account_sid
                << "/Messages";
        url_string = url.str();


        std::stringstream parameters;
        std::string parameter_string;
        parameters << "To=" << to_number << "&From=" << from_number 
                << "&Body=" << message_body_escaped;
        if (!picture_url.empty()) {
                parameters << "&MediaUrl=" << picture_url;
        }
        parameter_string = parameters.str();


        curl_easy_setopt(curl, CURLOPT_POST, 1);
        curl_easy_setopt(curl, CURLOPT_URL, url_string.c_str());
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, parameter_string.c_str());
        curl_easy_setopt(curl, CURLOPT_USERNAME, account_sid.c_str());
        curl_easy_setopt(curl, CURLOPT_PASSWORD, auth_token.c_str());
        if (!verbose) {
                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _null_write);
        } else {
                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _stream_write);
                curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_stream);
        }


        CURLcode res = curl_easy_perform(curl);
        curl_free(message_body_escaped);
        curl_easy_cleanup(curl);
        long http_code = 0;
        curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code);

        // Check for curl errors and Twilio failure status codes.
        if (res != CURLE_OK) {
                response = curl_easy_strerror(res);
                return false;
        } else if (http_code != 200 && http_code != 201) {
                response = response_stream.str();
                return false;
        } else {
                response = response_stream.str();
                return true;
        }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x6f0, %rsp            # imm = 0x6F0
movb 0x10(%rbp), %al
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq %r9, -0x38(%rbp)
andb $0x1, %al
movb %al, -0x39(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x640(%rbp)
leaq -0x1c8(%rbp), %rdi
callq 0x3140
leaq -0x1e8(%rbp), %rdi
callq 0x5060
movq -0x28(%rbp), %rsi
leaq -0x208(%rbp), %rdi
callq 0x50d0
jmp 0x4920
leaq -0x1e8(%rbp), %rdi
leaq -0x208(%rbp), %rsi
callq 0x51f0
leaq -0x208(%rbp), %rdi
callq 0x5400
jmp 0x49e9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x210(%rbp)
movl %eax, -0x214(%rbp)
movl -0x214(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x5027
movq -0x210(%rbp), %rdi
callq 0x3050
movq %rax, -0x220(%rbp)
movq -0x220(%rbp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq %rax, %rsi
movq -0x30(%rbp), %rdi
callq 0x3190
jmp 0x499a
movb $0x0, -0x1(%rbp)
movl $0x1, -0x224(%rbp)
callq 0x3280
jmp 0x49c8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x210(%rbp)
movl %eax, -0x214(%rbp)
callq 0x3280
jmp 0x49e4
jmp 0x5001
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x210(%rbp)
movl %eax, -0x214(%rbp)
jmp 0x5027
jmp 0x5027
leaq -0x1e8(%rbp), %rdi
callq 0x5440
cmpq $0x640, %rax            # imm = 0x640
jbe 0x4ab6
leaq -0x1b8(%rbp), %rdi
leaq 0x3979(%rip), %rsi      # 0x8388
callq 0x31f0
movq %rax, -0x648(%rbp)
jmp 0x4a1d
movq -0x648(%rbp), %rdi
leaq 0x3982(%rip), %rsi      # 0x83ad
callq 0x31f0
movq %rax, -0x650(%rbp)
jmp 0x4a39
leaq -0x1e8(%rbp), %rdi
callq 0x5440
movq -0x650(%rbp), %rdi
movq %rax, %rsi
callq 0x3340
movq %rax, -0x658(%rbp)
jmp 0x4a5d
movq -0x658(%rbp), %rdi
leaq 0x3a24(%rip), %rsi      # 0x848f
callq 0x31f0
jmp 0x4a72
leaq -0x248(%rbp), %rdi
leaq -0x1c8(%rbp), %rsi
callq 0x3240
jmp 0x4a87
movq -0x30(%rbp), %rdi
leaq -0x248(%rbp), %rsi
callq 0x31e0
leaq -0x248(%rbp), %rdi
callq 0x3270
movb $0x0, -0x1(%rbp)
movl $0x1, -0x224(%rbp)
jmp 0x5001
movl $0x3, %edi
callq 0x30f0
jmp 0x4ac2
callq 0x3310
movq %rax, -0x660(%rbp)
jmp 0x4ad0
movq -0x660(%rbp), %rax
movq %rax, -0x250(%rbp)
movq -0x250(%rbp), %rax
movq %rax, -0x670(%rbp)
movq -0x28(%rbp), %rdi
callq 0x3090
movq -0x670(%rbp), %rdi
movq %rax, %rsi
xorl %edx, %edx
callq 0x3250
movq %rax, -0x668(%rbp)
jmp 0x4b0f
movq -0x668(%rbp), %rax
movq %rax, -0x258(%rbp)
leaq -0x3e0(%rbp), %rdi
callq 0x3140
jmp 0x4b2b
leaq -0x400(%rbp), %rdi
callq 0x3160
leaq -0x3d0(%rbp), %rdi
leaq 0x388f(%rip), %rsi      # 0x83d4
callq 0x31f0
movq %rax, -0x678(%rbp)
jmp 0x4b53
movq -0x640(%rbp), %rsi
movq -0x678(%rbp), %rdi
callq 0x3130
movq %rax, -0x680(%rbp)
jmp 0x4b6f
movq -0x680(%rbp), %rdi
leaq 0x3883(%rip), %rsi      # 0x8400
callq 0x31f0
jmp 0x4b84
leaq -0x420(%rbp), %rdi
leaq -0x3e0(%rbp), %rsi
callq 0x3240
jmp 0x4b99
leaq -0x400(%rbp), %rdi
leaq -0x420(%rbp), %rsi
movq %rsi, -0x688(%rbp)
callq 0x31e0
movq -0x688(%rbp), %rdi
callq 0x3270
leaq -0x5a8(%rbp), %rdi
callq 0x3140
jmp 0x4bcd
leaq -0x5c8(%rbp), %rdi
callq 0x3160
leaq -0x598(%rbp), %rdi
leaq 0x3823(%rip), %rsi      # 0x840a
callq 0x31f0
movq %rax, -0x690(%rbp)
jmp 0x4bf5
movq -0x690(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x3130
movq %rax, -0x698(%rbp)
jmp 0x4c0e
movq -0x698(%rbp), %rdi
leaq 0x37f2(%rip), %rsi      # 0x840e
callq 0x31f0
movq %rax, -0x6a0(%rbp)
jmp 0x4c2a
movq -0x6a0(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x3130
movq %rax, -0x6a8(%rbp)
jmp 0x4c43
movq -0x6a8(%rbp), %rdi
leaq 0x37c4(%rip), %rsi      # 0x8415
callq 0x31f0
movq %rax, -0x6b0(%rbp)
jmp 0x4c5f
movq -0x6b0(%rbp), %rdi
movq -0x258(%rbp), %rsi
callq 0x31f0
jmp 0x4c74
movq -0x38(%rbp), %rdi
callq 0x3110
testb $0x1, %al
jne 0x4cf7
leaq -0x598(%rbp), %rdi
leaq 0x378d(%rip), %rsi      # 0x841c
callq 0x31f0
movq %rax, -0x6b8(%rbp)
jmp 0x4c9d
movq -0x6b8(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x3130
jmp 0x4caf
jmp 0x4cf7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x210(%rbp)
movl %eax, -0x214(%rbp)
jmp 0x4fe7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x210(%rbp)
movl %eax, -0x214(%rbp)
leaq -0x5c8(%rbp), %rdi
callq 0x3270
leaq -0x5a8(%rbp), %rdi
callq 0x3170
jmp 0x4fe7
leaq -0x5e8(%rbp), %rdi
leaq -0x5a8(%rbp), %rsi
callq 0x3240
jmp 0x4d0c
leaq -0x5c8(%rbp), %rdi
leaq -0x5e8(%rbp), %rsi
movq %rsi, -0x6c0(%rbp)
callq 0x31e0
movq -0x6c0(%rbp), %rdi
callq 0x3270
movq -0x250(%rbp), %rdi
xorl %eax, %eax
movl $0x2f, %esi
movl $0x1, %edx
callq 0x32c0
jmp 0x4d4c
movq -0x250(%rbp), %rax
movq %rax, -0x6c8(%rbp)
leaq -0x400(%rbp), %rdi
callq 0x3090
movq -0x6c8(%rbp), %rdi
movq %rax, %rdx
xorl %eax, %eax
movl $0x2712, %esi           # imm = 0x2712
callq 0x32c0
jmp 0x4d7e
movq -0x250(%rbp), %rax
movq %rax, -0x6d0(%rbp)
leaq -0x5c8(%rbp), %rdi
callq 0x3090
movq -0x6d0(%rbp), %rdi
movq %rax, %rdx
xorl %eax, %eax
movl $0x271f, %esi           # imm = 0x271F
callq 0x32c0
jmp 0x4db0
movq -0x640(%rbp), %rdi
movq -0x250(%rbp), %rax
movq %rax, -0x6d8(%rbp)
callq 0x3090
movq -0x6d8(%rbp), %rdi
movq %rax, %rdx
xorl %eax, %eax
movl $0x27bd, %esi           # imm = 0x27BD
callq 0x32c0
jmp 0x4de2
movq -0x640(%rbp), %rdi
movq -0x250(%rbp), %rax
movq %rax, -0x6e0(%rbp)
addq $0x20, %rdi
callq 0x3090
movq -0x6e0(%rbp), %rdi
movq %rax, %rdx
xorl %eax, %eax
movl $0x27be, %esi           # imm = 0x27BE
callq 0x32c0
jmp 0x4e18
testb $0x1, -0x39(%rbp)
jne 0x4e3c
movq -0x250(%rbp), %rdi
leaq -0x5dc(%rip), %rdx      # 0x4850
xorl %eax, %eax
movl $0x4e2b, %esi           # imm = 0x4E2B
callq 0x32c0
jmp 0x4e3a
jmp 0x4e76
movq -0x250(%rbp), %rdi
leaq -0x5da(%rip), %rdx      # 0x4870
xorl %eax, %eax
movl $0x4e2b, %esi           # imm = 0x4E2B
callq 0x32c0
jmp 0x4e58
movq -0x250(%rbp), %rdi
xorl %eax, %eax
movl $0x2711, %esi           # imm = 0x2711
leaq -0x1c8(%rbp), %rdx
callq 0x32c0
jmp 0x4e74
jmp 0x4e76
movq -0x250(%rbp), %rdi
callq 0x3230
movl %eax, -0x6e4(%rbp)
jmp 0x4e8a
movl -0x6e4(%rbp), %eax
movl %eax, -0x5ec(%rbp)
movq -0x258(%rbp), %rdi
callq 0x3030
jmp 0x4ea4
movq -0x250(%rbp), %rdi
callq 0x30c0
jmp 0x4eb2
movq $0x0, -0x5f8(%rbp)
movq -0x250(%rbp), %rdi
xorl %eax, %eax
movl $0x200002, %esi         # imm = 0x200002
leaq -0x5f8(%rbp), %rdx
callq 0x3300
jmp 0x4ed9
cmpl $0x0, -0x5ec(%rbp)
je 0x4f1b
movl -0x5ec(%rbp), %edi
callq 0x31a0
movq %rax, -0x6f0(%rbp)
jmp 0x4ef6
movq -0x6f0(%rbp), %rsi
movq -0x30(%rbp), %rdi
callq 0x3190
jmp 0x4f08
movb $0x0, -0x1(%rbp)
movl $0x1, -0x224(%rbp)
jmp 0x4fb5
cmpq $0xc8, -0x5f8(%rbp)
je 0x4f76
cmpq $0xc9, -0x5f8(%rbp)
je 0x4f76
leaq -0x618(%rbp), %rdi
leaq -0x1c8(%rbp), %rsi
callq 0x3240
jmp 0x4f4a
movq -0x30(%rbp), %rdi
leaq -0x618(%rbp), %rsi
callq 0x31e0
leaq -0x618(%rbp), %rdi
callq 0x3270
movb $0x0, -0x1(%rbp)
movl $0x1, -0x224(%rbp)
jmp 0x4fb5
leaq -0x638(%rbp), %rdi
leaq -0x1c8(%rbp), %rsi
callq 0x3240
jmp 0x4f8b
movq -0x30(%rbp), %rdi
leaq -0x638(%rbp), %rsi
callq 0x31e0
leaq -0x638(%rbp), %rdi
callq 0x3270
movb $0x1, -0x1(%rbp)
movl $0x1, -0x224(%rbp)
leaq -0x5c8(%rbp), %rdi
callq 0x3270
leaq -0x5a8(%rbp), %rdi
callq 0x3170
leaq -0x400(%rbp), %rdi
callq 0x3270
leaq -0x3e0(%rbp), %rdi
callq 0x3170
jmp 0x5001
leaq -0x400(%rbp), %rdi
callq 0x3270
leaq -0x3e0(%rbp), %rdi
callq 0x3170
jmp 0x5027
leaq -0x1e8(%rbp), %rdi
callq 0x5400
leaq -0x1c8(%rbp), %rdi
callq 0x3170
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x6f0, %rsp            # imm = 0x6F0
popq %rbp
retq
leaq -0x1e8(%rbp), %rdi
callq 0x5400
leaq -0x1c8(%rbp), %rdi
callq 0x3170
movq -0x210(%rbp), %rdi
callq 0x3220
movq %rax, %rdi
callq 0x3ce0
nopw %cs:(%rax,%rax)
nopl (%rax)