#!/usr/bin/perl

use strict;
use warnings;

use Test::More;

use Device::Chip::Base::RegisteredI2C;

package TestChip {
   use base qw( Device::Chip::Base::RegisteredI2C );
}

# TODO: extract this to a handy t:: file
my @writes;
my @reads;
package TestAdapter {
   use base qw( Device::Chip::Adapter );
   sub make_protocol_I2C { return Future->done( shift ) }

   sub write {
      push @writes, $_[1];
      Future->done();
   }

   sub write_then_read {
      push @writes, $_[1];
      Future->done( shift @reads );
   }
}

my $chip = Device::Chip::Base::RegisteredI2C->new;
$chip->mount( "TestAdapter" )->get;

# write
{
   @writes = ();

   $chip->write_reg( 123, "A" )->get;

   is_deeply( \@writes, [ pack "C a", 123, "A" ], '->write_reg' );
}

# read
{
   @writes = ();
   @reads = ( "B" );

   my $val = $chip->read_reg( 123 )->get;

   is( $val, "B", '->read_reg value' );
   is_deeply( \@writes, [ pack "C", 123 ], '->read_reg write' );
}

# cached read
{
   @writes = ();
   @reads = ( "\x20" );

   is( $chip->cached_read_reg( 2, 1 )->get, "\x20",
         '->cached_read_reg the first time' );
   is_deeply( \@writes, [ pack "C", 2 ], '->cached_read_reg writes addr' );
   @writes = ();

   is( $chip->cached_read_reg( 2, 1 )->get, "\x20",
         '->cached_read_reg the second time' );
   is_deeply( \@writes, [], '->cached_read_reg did not write addr' );

   $chip->write_reg( 2, "\x25" )->get;
   @writes = ();
   is_deeply( $chip->cached_read_reg( 2, 1 )->get, "\x25",
         '->cached_read_reg snoops on writes' );
   is_deeply( \@writes, [],
         '->cached_read_reg does not readdress after write snoop' );

   @reads = ( "\x30" );
   $chip->read_reg( 2, 1 )->get;
   @writes = ();
   is_deeply( $chip->cached_read_reg( 2, 1 )->get, "\x30",
         '->cached_read_reg snoops on reads' );
   is_deeply( \@writes, [],
         '->cached_read_reg does not readdress after read snoop' );
}

# cached write
{
   @writes = ();

   $chip->cached_write_reg( 3, "\x40" )->get;
   is_deeply( \@writes, [ pack "C a", 3, "\x40" ],
         '->cached_write_reg writes on cache miss' );

   @writes = ();
   $chip->cached_write_reg( 3, "\x40" )->get;
   is_deeply( \@writes, [],
         '->cached_write_reg does not write a duplicate value' );

   @writes = ();
   $chip->cached_write_reg( 3, "\x41" )->get;
   is_deeply( \@writes, [ pack "C a", 3, "\x41" ],
         '->cached_write_reg writes a new value' );
}

done_testing;
