package STIX::Common::Identifier;

use 5.010001;
use strict;
use warnings;
use utf8;

use overload '""' => \&to_string, fallback => 1;

use Carp;
use Moo;

around BUILDARGS => sub {

    my ($orig, $class, @args) = @_;

    return {value => $args[0]} if @args == 1;
    return $class->$orig(@args);

};

my $IDENTIFIER_REGEXP
    = qr{^[a-z][a-z0-9-]+[a-z0-9]--[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$};

has value => (
    is     => 'rw',
    isa    => sub { Carp::croak 'MUST be STIX identifier' unless $_[0] =~ /$IDENTIFIER_REGEXP/ },
    coerce => sub { _parse($_[0]) }
);

sub _parse {

    return $_[0]     if $_[0] =~ /$IDENTIFIER_REGEXP/;
    return $_[0]->id if (ref($_[0]));

}

sub to_string { shift->value }
sub TO_JSON   { shift->value }


1;

=encoding utf-8

=head1 NAME

STIX::Common::Identifier - Identifier type

=head1 SYNOPSIS

    use STIX::Common::Identifier;

    my $bundle = STIX::Bundle->new( ... );

    my $id = STIX::Common::Identifier->new(value => $bundle);

    say $id; # bundle--0e60b95c-3e54-4097-9a0a-d7d637514312


=head1 DESCRIPTION

An identifier uniquely identifies a STIX Object and MAY do so in a deterministic
way. A deterministic identifier means that the identifier generated by more than
one producer for the exact same STIX Object using the same namespace,
"ID Contributing Properties", and UUID method will have the exact same identifier
value.

All identifiers, excluding those used in the deprecated Cyber Observable Container,
MUST follow the form object-type--UUID, where object-type is the exact value
(all type names are lowercase strings, by definition) from the type property of
the object being identified or referenced and where the UUID MUST be an
RFC 4122-compliant UUID.

=head2 PROPERTIES

=over

=item value

=back

=head2 HELPERS

=over

=item $identifier->TO_JSON

Encode the object in JSON.

=item $identifier->to_string

Encode the object in JSON.

=back


=head1 SUPPORT

=head2 Bugs / Feature Requests

Please report any bugs or feature requests through the issue tracker
at L<https://github.com/giterlizzi/perl-STIX/issues>.
You will be notified automatically of any progress on your issue.

=head2 Source Code

This is open source software.  The code repository is available for
public review and contribution under the terms of the license.

L<https://github.com/giterlizzi/perl-STIX>

    git clone https://github.com/giterlizzi/perl-STIX.git


=head1 AUTHOR

=over 4

=item * Giuseppe Di Terlizzi <gdt@cpan.org>

=back


=head1 LICENSE AND COPYRIGHT

This software is copyright (c) 2024 by Giuseppe Di Terlizzi.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
