package SMS::Send::NANP::Twilio;
use strict;
use warnings;
use URI;
use JSON::XS qw{decode_json};
use base qw{SMS::Send::Driver::WebService};

our $VERSION = '0.02';

=head1 NAME

SMS::Send::NANP::Twilio - SMS::Send driver for Twilio

=head1 SYNOPSIS

  Configure /etc/SMS-Send.ini

  [NANP::Twilio]
  username=onestring
  password=anotherstring
  from=+12025551212
  ;sid=Copilot_MessagingServiceSid_instead_of_from

  use SMS::Send;
  my $sms     = SMS::Send->new('NANP::Twilio');
  my $success = $sms->send_sms(text=> 'Hello World!', to =>'+17035551212');

  use SMS::Send::NANP::Twilio;
  my $sms     = SMS::Send::NANP::Twilio->new;
  my $success = $sms->send_sms(text=> 'Hello World!', to =>'+17035551212');
  my $json    = $sms->{__content};
  my $href    = $sms->{__data};

=head1 DESCRIPTION

SMS::Send driver for Twilio

=head2 send_sms

Sends SMS Message via Twilio web service and returns 1 or 0 will die on critical error.

  my $status = $sms->send_sms(text=> 'Hello World!', to =>'+17035551212');

=over

=item to

Passed as "To" in the posted form data. The destination phone number for SMS/MMS or a Channel user address for other 3rd party channels. Destination phone numbers should be formatted with a '+' and country code e.g., +16175551212 (E.164 format).

=item text

Passed as "Body" in the posted form data. The text of the message you want to send, limited to 1600 characters.

=back

=cut

sub send_sms {
  my $self             = shift;
  my %argv             = @_;
  my $to               = $argv{'to'} or die('Error: to address required');
  my $text             = defined($argv{'text'}) ? $argv{'text'} : '';
  my $url              = $self->url; #isa URI::https
  my @form             = (To => $to, Body => $text);
  my $sid              = $self->sid; #isa undef || Str
  if ($sid) {
    push @form, MessagingServiceSid => $sid;
  } else {
    my $from = $self->from or die('Error: Properties "from" or "sid" must be configured.');
    push @form, From => $from;
  }
  my $response         = $self->uat->post_form($url, \@form); #isa HASH from HTTP::Tiny
  die(sprintf("HTTP Error: %s %s", $response->{'status'}, $response->{'reason'})) unless $response->{'success'};
  my $content          = $response->{'content'};
  $self->{'__content'} = $content;
  my $data             = decode_json($content);
  $self->{'__data'}    = $data;
  my $status           = $data->{'status'};
  #queued when using from
  #accepted when using copilot
  return ($status eq 'queued' or $status eq 'accepted') ? 1 : 0;
}

=head1 Properties

Properties may be stored in /etc/SMS-Send.ini.

=head2 username

The "Account SID" is passed on the URL and sent as the username for basic authentication credentials

=cut

#see SMS::Send::Driver::WebService->username

=head2 password

The "Auth Token" sent as password for basic authentication credentials

=cut

#see SMS::Send::Driver::WebService->password

=head2 from

The "From" parameter passed in the posted form

A Twilio phone number (in E.164 format), alphanumeric sender ID or a Channel Endpoint address enabled for the type of message you wish to send. Phone numbers or short codes purchased from Twilio work here. You cannot (for example) spoof messages from your own cell phone number.

=cut

sub from {
  my $self=shift;
  $self->{'from'}=shift if @_;
  $self->{'from'}=$self->cfg_property('from', $self->_from_default) unless defined $self->{'from'};
  return $self->{'from'};
}
 
sub _from_default {undef};

=head2 sid

The "MessagingServiceSid" parameter passed in the posted form

The 34 character unique id of the Messaging Service you want to associate with this Message. Set this parameter to use the Messaging Service Settings and Copilot Features you have configured. When only this parameter is set, Twilio will use your enabled Copilot Features to select the From phone number for delivery.

=cut

sub sid {
  my $self=shift;
  $self->{'sid'}=shift if @_;
  $self->{'sid'}=$self->cfg_property('sid', $self->_sid_default) unless defined $self->{'sid'};
  return $self->{'sid'};
}

sub _sid_default {undef};

=head2 url

Returns a L<URI> object for the Messages.json resource at api.twilio.com

=cut

sub url {
  my $self = shift;
  my $url  = URI->new(join '/', 'https://api.twilio.com/2010-04-01/Accounts', $self->username, 'Messages.json');
  $url->userinfo(join ':', $self->username, $self->password);
  return $url;
};

=head1 SEE ALSO

L<SMS::Send::Driver::WebService>, L<SMS::Send>, L<https://www.twilio.com/docs/api/messaging/send-messages>

=head1 AUTHOR

Michael Davis

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2018 by Michael Davis

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.10.1 or, at your option, any later version of Perl 5 you may have available.

=cut

1;
