package Finance::IG::REST::Client; 
use JSON; 
use Digest::MD5 qw(md5 md5_hex md5_base64);
my $datapath; 
my $content; 

use vars '$AUTOLOAD';

my $fdebug=0; # print debug infor relating to files etc. 


=encoding utf8

=head1 NAME

Finance::IG::REST::Client - Module to mock REST::Client when testing Finance::IG

=head1 DESCRIPTION

This module mocks REST::CLient. Rather than sending request via the internet a series of files with names derived from a hash of 
url and parameters are retrieved and contain the expected respons. 

The module is intended to be used with use Package::Alias, see below. 

The files can be generated with the module in Testing::Record::REST::Client, but you will need an IG account to run
generate files as you will need to really access the IG site. 

=head1 VERSION 

Version 0.08

=cut

our $VERSION=0.08; 

=head1 SYNOPSIS


    use Package::Alias 'REST::Client'=>'Finance::IG::REST::Client' ; 
    use REST::Client; 

Or     
    use Package::Alias 'REST::Client'=>'Finance::IG::REST::Client' ; 
    use Some::Other::Module::That::UsesREST::Client' 

    calls to Some::Other... # All use the mocked REST::Client; 

=head1 SUBROUTINES/METHODS

This is a list of the implemented methods. We only implement those needed for testing Finance::IG

=head2 new 

No parameters, returns a blessed reference to the item 

=cut 


sub AUTOLOAD
{
   $AUTOLOAD =~ s/.*:://; 

    for my $name (qw/
                 GET PUT _buildAccessors _buildUseragent getUseragent setUseragent 
                 request _prepareURL getHost getTimeout
                 getCert getCa getPkcs12 getFollow getContentFile responseCode
                 responseHeader responseContent setHost 
                 /)
    { 
       if ($AUTOLOAD eq $name)
       {
         return 1; 
       } 
    }

   shift->${\"NEXT::$AUTOLOAD"}(@_); 
}

=head2 whoami 

This function is not implemented in the original REST::Client. It returns a string 

        This is Finance::IG::REST::Client 

so that you may know you have succesfully instantiated the right module. 

=cut

sub whoami
{ 
  return "This is Finance::IG::REST::Client"; 
} 

BEGIN { 
  my $rcpath; 
  my $thispath=$INC{'Finance/IG/REST/Client.pm'}; 
  $datapath=$thispath; 
  $datapath=~s#/[^/]+$##; 
  $datapath=~s#/[^/]+$##; 
  $datapath=~s#/[^/]+$##; 
  $datapath=~s#/[^/]+$##; 
  $datapath=~s#/[^/]+$##; 
  $datapath=~s#/[^/]+$##; 

  $datapath=$datapath."/Data"; 
#  mkdir $datapath; 
} 

#=pod 
#
#for my $name (qw/
#                 PUT _buildAccessors _buildUseragent getUseragent setUseragent 
#                 request _prepareURL getHost getTimeout
#                 getCert getCa getPkcs12 getFollow getContentFile responseCode
#                 responseHeader responseContent setHost
#                /
#             )
#{
#  no strict 'refs';
#  no warnings 'redefine';
# 
#  *{"Finance::IG::REST::Client::$name"} = sub {}; 
#} 
#
#=cut

sub new
{ 
  return bless {}; 
} 

=head2 POST 

Mocks the REST::CLient POST function 

=cut

sub POST{ 
  my ($self,$url,$jdata,$headers)=@_; 
  local $"=', '; 

  my $jheaders=JSON->new->canonical->encode($headers);  
  if ($jdata)
  { 
    $jdata=~s/("identifier":)("[^"]+")/$1"igusername"/g; 
    $jdata=~s/("password":)("[^"]+")/$1"ig_correct_password"/g; 
  } 
  $jheaders=~s/("X-IG-API-KEY":)("[^"]+)"/$1"securitykey"/g;
  $jheaders=~s/("X-SECURITY-TOKEN":)("[^"]+)"/$1"."/g;
  $jheaders=~s/("CST":)("[^"]+)"/$1"."/g;

  $fdebug and print " url=$url\n jdata=$jdata\n jheaders=$jheaders\n"; 
   
  my $file="$datapath/".md5_hex($url,$jdata,$jheaders).".txt"; 
  $fdebug and print "Reading $file\n"; 
  open(F,"<",$file) or die "Cannot open file $file for read"; 
  binmode(F); 
  read F, $content, 1000000; 
  close F; 
}
 
=head2 responseCode

returns the success response code (200) 

=cut 

sub responseCode
{
  return 200; 
} 

=head2 responseContent

returns the mocked content of the response

=cut 

sub responseContent
{
  $content=~s/,"headers":\{[^}]+\}\}//; 
  $content=~s/\{"content"://; 
  return $content; 
}

=head2 XSECURITYTOKEN

=cut 

sub XSECURITYTOKEN
{ 
   die $content; 
} 

=head2 responseHeader

returns the mocked response header. 

=cut 

sub responseHeader
{
   my ($self,$header)=@_; 
   my $c=decode_json($content); 
   my $headers=$c->{headers}; 
   return $headers->{$header}; 
} 

=head2 CST 

Dummy function. 

=cut 

sub CST
{
}

=head2 GET 

Dummy function, calls POST

=cut 

sub GET
{
  my ($self,$url,$headers)=@_; 
  POST($self,$url,undef,$headers); 
}
1;