package Timer;

use Time::HiRes 'time';
use Carp 'carp';
use strict;
use warnings;

my %prec;

sub TIESCALAR { bless \time, $_[0] }
sub FETCH { sprintf "%.*f", $prec{$_[0]}, time - ${$_[0]} }
sub STORE { ${$_[0]} = $_[1] }

sub FETCH_SCALAR_ATTRIBUTES {
  my $class = shift;
  return qw( Timer );
}

sub MODIFY_SCALAR_ATTRIBUTES {
  my $class = shift;
  my $ref = shift;
  my @unhandled;

  for (@_) {
    my ($attr, $args) = m{ ([^(]+) (?: \( (.*) \) )? }sx;

    if ($attr eq 'Timer') {
      my $precision;

      if (not defined $args) { $precision = 0 }
      elsif ($args =~ /^(\d*)/) { $precision = $1 }
      elsif ($args =~ /^([mun]s)$/) {
        $precision = {qw( s 0 m 3 u 6 n 9 )}->{$1};
      }
      else {
        carp "unsupported precision '$args'";
      }

      my $obj = tie $$ref, 'Timer';
      $prec{$obj} = $precision;
    }
    else {
      push @unhandled, defined($args) ? "$attr($args)" : $attr;
    }
  }

  return @unhandled;
}

1;
