package CSAF::Type::Vulnerability;

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

use Carp;

use CSAF::Type::Acknowledgments;
use CSAF::Type::CWE;
use CSAF::Type::Flags;
use CSAF::Type::IDs;
use CSAF::Type::Involvements;
use CSAF::Type::Notes;
use CSAF::Type::ProductStatus;
use CSAF::Type::References;
use CSAF::Type::Remediations;
use CSAF::Type::Scores;
use CSAF::Type::Threats;

use CSAF::Util qw(parse_datetime);

use Moo;
extends 'CSAF::Type::Base';


has title => (is => 'rw');
has cve   => (is => 'rw', isa => sub { Carp::carp 'Malformed CVE ID' if ($_[0] && $_[0] !~ /^CVE-\d{4}-\d{4,7}$/) });
has discovery_date => (is => 'rw', coerce => \&parse_datetime);
has release_date   => (is => 'rw', coerce => \&parse_datetime);

sub cwe {
    my ($self, %params) = @_;
    $self->{cwe} ||= CSAF::Type::CWE->new(%params);
}

sub product_status {
    my ($self, %params) = @_;
    $self->{product_status} ||= CSAF::Type::ProductStatus->new(%params);
}

sub notes {
    my $self = shift;
    $self->{notes} ||= CSAF::Type::Notes->new(@_);
}

sub references {
    my $self = shift;
    $self->{references} ||= CSAF::Type::References->new(@_);
}

sub scores {
    my ($self, %params) = @_;
    $self->{scores} ||= CSAF::Type::Scores->new(%params);
}

sub acknowledgments {
    my $self = shift;
    $self->{acknowledgments} ||= CSAF::Type::Acknowledgments->new(@_);
}

sub remediations {
    my $self = shift;
    $self->{remediations} ||= CSAF::Type::Remediations->new(@_);
}

sub threats {
    my $self = shift;
    $self->{threats} ||= CSAF::Type::Threats->new(@_);
}

sub ids {
    my $self = shift;
    $self->{ids} ||= CSAF::Type::IDs->new(@_);
}

sub involvements {
    my $self = shift;
    $self->{involvements} ||= CSAF::Type::Involvements->new(@_);
}

sub flags {
    my $self = shift;
    $self->{flags} ||= CSAF::Type::Flags->new(@_);
}


sub TO_CSAF {

    my $self = shift;

    my $output = {};

    $output->{cve}   = $self->cve   if ($self->cve);
    $output->{title} = $self->title if ($self->title);

    $output->{discovery_date} = parse_datetime($self->discovery_date) if ($self->discovery_date);
    $output->{release_date}   = parse_datetime($self->release_date)   if ($self->release_date);

    if ($self->cwe->id) {
        $output->{cwe} = $self->cwe;
    }

    if (@{$self->acknowledgments->items}) {
        $output->{acknowledgments} = $self->acknowledgments;
    }

    if (@{$self->notes->items}) {
        $output->{notes} = $self->notes;
    }

    if (@{$self->scores->items}) {
        $output->{scores} = $self->scores;
    }

    if (@{$self->remediations->items}) {
        $output->{remediations} = $self->remediations;
    }

    if (@{$self->references->items}) {
        $output->{references} = $self->references;
    }

    if (@{$self->involvements->items}) {
        $output->{involvements} = $self->involvements;
    }

    if (my $product_status = $self->product_status->TO_CSAF) {
        $output->{product_status} = $product_status;
    }

    if (my $flags = $self->flags->TO_CSAF) {
        $output->{flags} = $flags if (@$flags);    # TODO
    }

    if (my $ids = $self->ids->TO_CSAF) {
        $output->{ids} = $ids if (@$ids);          # TODO
    }

    return $output;

}

1;

__END__

=encoding utf-8

=head1 NAME

CSAF::Type::Vulnerability

=head1 SYNOPSIS

    use CSAF::Type::Vulnerability;
    my $type = CSAF::Type::Vulnerability->new( );


=head1 DESCRIPTION



=head2 METHODS

L<CSAF::Type::Vulnerability> inherits all methods from L<CSAF::Type::Base> and implements the following new ones.

=over

=item $type->acknowledgments

=item $type->cve

=item $type->cwe

=item $type->discovery_date

=item $type->flags

=item $type->ids

=item $type->involvements

=item $type->notes

=item $type->product_status

=item $type->references

=item $type->release_date

=item $type->remediations

=item $type->scores

=item $type->threats

=item $type->title

=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-CSAF/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-CSAF>

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


=head1 AUTHOR

=over 4

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

=back


=head1 LICENSE AND COPYRIGHT

This software is copyright (c) 2023-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
