<?php

namespace Microsoft\Graph\Generated\Models\Security;

use DateTime;
use Microsoft\Graph\Generated\Models\Entity;
use Microsoft\Kiota\Abstractions\Serialization\Parsable;
use Microsoft\Kiota\Abstractions\Serialization\ParseNode;
use Microsoft\Kiota\Abstractions\Serialization\SerializationWriter;
use Microsoft\Kiota\Abstractions\Types\TypeUtils;

class Vulnerability extends Entity implements Parsable 
{
    /**
     * Instantiates a new Vulnerability and sets the default values.
    */
    public function __construct() {
        parent::__construct();
    }

    /**
     * Creates a new instance of the appropriate class based on discriminator value
     * @param ParseNode $parseNode The parse node to use to read the discriminator value and create the object
     * @return Vulnerability
    */
    public static function createFromDiscriminatorValue(ParseNode $parseNode): Vulnerability {
        return new Vulnerability();
    }

    /**
     * Gets the activeExploitsObserved property value. Indicates whether this vulnerability has any known exploits associated to known bad actors.
     * @return bool|null
    */
    public function getActiveExploitsObserved(): ?bool {
        $val = $this->getBackingStore()->get('activeExploitsObserved');
        if (is_null($val) || is_bool($val)) {
            return $val;
        }
        throw new \UnexpectedValueException("Invalid type found in backing store for 'activeExploitsObserved'");
    }

    /**
     * Gets the articles property value. Articles related to this vulnerability.
     * @return array<Article>|null
    */
    public function getArticles(): ?array {
        $val = $this->getBackingStore()->get('articles');
        if (is_array($val) || is_null($val)) {
            TypeUtils::validateCollectionValues($val, Article::class);
            /** @var array<Article>|null $val */
            return $val;
        }
        throw new \UnexpectedValueException("Invalid type found in backing store for 'articles'");
    }

    /**
     * Gets the commonWeaknessEnumerationIds property value. Community-defined common weakness enumerations (CWE).
     * @return array<string>|null
    */
    public function getCommonWeaknessEnumerationIds(): ?array {
        $val = $this->getBackingStore()->get('commonWeaknessEnumerationIds');
        if (is_array($val) || is_null($val)) {
            TypeUtils::validateCollectionValues($val, 'string');
            /** @var array<string>|null $val */
            return $val;
        }
        throw new \UnexpectedValueException("Invalid type found in backing store for 'commonWeaknessEnumerationIds'");
    }

    /**
     * Gets the components property value. Components related to this vulnerability article.
     * @return array<VulnerabilityComponent>|null
    */
    public function getComponents(): ?array {
        $val = $this->getBackingStore()->get('components');
        if (is_array($val) || is_null($val)) {
            TypeUtils::validateCollectionValues($val, VulnerabilityComponent::class);
            /** @var array<VulnerabilityComponent>|null $val */
            return $val;
        }
        throw new \UnexpectedValueException("Invalid type found in backing store for 'components'");
    }

    /**
     * Gets the createdDateTime property value. The date and time when this vulnerability article was first created.
     * @return DateTime|null
    */
    public function getCreatedDateTime(): ?DateTime {
        $val = $this->getBackingStore()->get('createdDateTime');
        if (is_null($val) || $val instanceof DateTime) {
            return $val;
        }
        throw new \UnexpectedValueException("Invalid type found in backing store for 'createdDateTime'");
    }

    /**
     * Gets the cvss2Summary property value. The cvss2Summary property
     * @return CvssSummary|null
    */
    public function getCvss2Summary(): ?CvssSummary {
        $val = $this->getBackingStore()->get('cvss2Summary');
        if (is_null($val) || $val instanceof CvssSummary) {
            return $val;
        }
        throw new \UnexpectedValueException("Invalid type found in backing store for 'cvss2Summary'");
    }

    /**
     * Gets the cvss3Summary property value. The cvss3Summary property
     * @return CvssSummary|null
    */
    public function getCvss3Summary(): ?CvssSummary {
        $val = $this->getBackingStore()->get('cvss3Summary');
        if (is_null($val) || $val instanceof CvssSummary) {
            return $val;
        }
        throw new \UnexpectedValueException("Invalid type found in backing store for 'cvss3Summary'");
    }

    /**
     * Gets the description property value. The description property
     * @return FormattedContent|null
    */
    public function getDescription(): ?FormattedContent {
        $val = $this->getBackingStore()->get('description');
        if (is_null($val) || $val instanceof FormattedContent) {
            return $val;
        }
        throw new \UnexpectedValueException("Invalid type found in backing store for 'description'");
    }

    /**
     * Gets the exploits property value. Known exploits for this vulnerability.
     * @return array<Hyperlink>|null
    */
    public function getExploits(): ?array {
        $val = $this->getBackingStore()->get('exploits');
        if (is_array($val) || is_null($val)) {
            TypeUtils::validateCollectionValues($val, Hyperlink::class);
            /** @var array<Hyperlink>|null $val */
            return $val;
        }
        throw new \UnexpectedValueException("Invalid type found in backing store for 'exploits'");
    }

    /**
     * Gets the exploitsAvailable property value. Indicates whether this vulnerability has exploits in public sources (such as Packetstorm or Exploit-DB) online.
     * @return bool|null
    */
    public function getExploitsAvailable(): ?bool {
        $val = $this->getBackingStore()->get('exploitsAvailable');
        if (is_null($val) || is_bool($val)) {
            return $val;
        }
        throw new \UnexpectedValueException("Invalid type found in backing store for 'exploitsAvailable'");
    }

    /**
     * The deserialization information for the current model
     * @return array<string, callable(ParseNode): void>
    */
    public function getFieldDeserializers(): array {
        $o = $this;
        return array_merge(parent::getFieldDeserializers(), [
            'activeExploitsObserved' => fn(ParseNode $n) => $o->setActiveExploitsObserved($n->getBooleanValue()),
            'articles' => fn(ParseNode $n) => $o->setArticles($n->getCollectionOfObjectValues([Article::class, 'createFromDiscriminatorValue'])),
            'commonWeaknessEnumerationIds' => function (ParseNode $n) {
                $val = $n->getCollectionOfPrimitiveValues();
                if (is_array($val)) {
                    TypeUtils::validateCollectionValues($val, 'string');
                }
                /** @var array<string>|null $val */
                $this->setCommonWeaknessEnumerationIds($val);
            },
            'components' => fn(ParseNode $n) => $o->setComponents($n->getCollectionOfObjectValues([VulnerabilityComponent::class, 'createFromDiscriminatorValue'])),
            'createdDateTime' => fn(ParseNode $n) => $o->setCreatedDateTime($n->getDateTimeValue()),
            'cvss2Summary' => fn(ParseNode $n) => $o->setCvss2Summary($n->getObjectValue([CvssSummary::class, 'createFromDiscriminatorValue'])),
            'cvss3Summary' => fn(ParseNode $n) => $o->setCvss3Summary($n->getObjectValue([CvssSummary::class, 'createFromDiscriminatorValue'])),
            'description' => fn(ParseNode $n) => $o->setDescription($n->getObjectValue([FormattedContent::class, 'createFromDiscriminatorValue'])),
            'exploits' => fn(ParseNode $n) => $o->setExploits($n->getCollectionOfObjectValues([Hyperlink::class, 'createFromDiscriminatorValue'])),
            'exploitsAvailable' => fn(ParseNode $n) => $o->setExploitsAvailable($n->getBooleanValue()),
            'hasChatter' => fn(ParseNode $n) => $o->setHasChatter($n->getBooleanValue()),
            'lastModifiedDateTime' => fn(ParseNode $n) => $o->setLastModifiedDateTime($n->getDateTimeValue()),
            'priorityScore' => fn(ParseNode $n) => $o->setPriorityScore($n->getIntegerValue()),
            'publishedDateTime' => fn(ParseNode $n) => $o->setPublishedDateTime($n->getDateTimeValue()),
            'references' => fn(ParseNode $n) => $o->setReferences($n->getCollectionOfObjectValues([Hyperlink::class, 'createFromDiscriminatorValue'])),
            'remediation' => fn(ParseNode $n) => $o->setRemediation($n->getObjectValue([FormattedContent::class, 'createFromDiscriminatorValue'])),
            'severity' => fn(ParseNode $n) => $o->setSeverity($n->getEnumValue(VulnerabilitySeverity::class)),
        ]);
    }

    /**
     * Gets the hasChatter property value. Indicates whether chatter about this vulnerability has been discovered online.
     * @return bool|null
    */
    public function getHasChatter(): ?bool {
        $val = $this->getBackingStore()->get('hasChatter');
        if (is_null($val) || is_bool($val)) {
            return $val;
        }
        throw new \UnexpectedValueException("Invalid type found in backing store for 'hasChatter'");
    }

    /**
     * Gets the lastModifiedDateTime property value. The date and time when this vulnerability article was most recently updated.
     * @return DateTime|null
    */
    public function getLastModifiedDateTime(): ?DateTime {
        $val = $this->getBackingStore()->get('lastModifiedDateTime');
        if (is_null($val) || $val instanceof DateTime) {
            return $val;
        }
        throw new \UnexpectedValueException("Invalid type found in backing store for 'lastModifiedDateTime'");
    }

    /**
     * Gets the priorityScore property value. A unique algorithm that reflects the priority of a vulnerability based on the CVSS score, exploits, chatter, and linkage to malware. This property also evaluates the recency of these components so users can understand which vulnerability should be remediated first.
     * @return int|null
    */
    public function getPriorityScore(): ?int {
        $val = $this->getBackingStore()->get('priorityScore');
        if (is_null($val) || is_int($val)) {
            return $val;
        }
        throw new \UnexpectedValueException("Invalid type found in backing store for 'priorityScore'");
    }

    /**
     * Gets the publishedDateTime property value. The date and time when this vulnerability article was published.
     * @return DateTime|null
    */
    public function getPublishedDateTime(): ?DateTime {
        $val = $this->getBackingStore()->get('publishedDateTime');
        if (is_null($val) || $val instanceof DateTime) {
            return $val;
        }
        throw new \UnexpectedValueException("Invalid type found in backing store for 'publishedDateTime'");
    }

    /**
     * Gets the references property value. Reference links where further information can be learned about this vulnerability.
     * @return array<Hyperlink>|null
    */
    public function getReferences(): ?array {
        $val = $this->getBackingStore()->get('references');
        if (is_array($val) || is_null($val)) {
            TypeUtils::validateCollectionValues($val, Hyperlink::class);
            /** @var array<Hyperlink>|null $val */
            return $val;
        }
        throw new \UnexpectedValueException("Invalid type found in backing store for 'references'");
    }

    /**
     * Gets the remediation property value. Any known remediation steps.
     * @return FormattedContent|null
    */
    public function getRemediation(): ?FormattedContent {
        $val = $this->getBackingStore()->get('remediation');
        if (is_null($val) || $val instanceof FormattedContent) {
            return $val;
        }
        throw new \UnexpectedValueException("Invalid type found in backing store for 'remediation'");
    }

    /**
     * Gets the severity property value. The severity property
     * @return VulnerabilitySeverity|null
    */
    public function getSeverity(): ?VulnerabilitySeverity {
        $val = $this->getBackingStore()->get('severity');
        if (is_null($val) || $val instanceof VulnerabilitySeverity) {
            return $val;
        }
        throw new \UnexpectedValueException("Invalid type found in backing store for 'severity'");
    }

    /**
     * Serializes information the current object
     * @param SerializationWriter $writer Serialization writer to use to serialize this model
    */
    public function serialize(SerializationWriter $writer): void {
        parent::serialize($writer);
        $writer->writeBooleanValue('activeExploitsObserved', $this->getActiveExploitsObserved());
        $writer->writeCollectionOfObjectValues('articles', $this->getArticles());
        $writer->writeCollectionOfPrimitiveValues('commonWeaknessEnumerationIds', $this->getCommonWeaknessEnumerationIds());
        $writer->writeCollectionOfObjectValues('components', $this->getComponents());
        $writer->writeDateTimeValue('createdDateTime', $this->getCreatedDateTime());
        $writer->writeObjectValue('cvss2Summary', $this->getCvss2Summary());
        $writer->writeObjectValue('cvss3Summary', $this->getCvss3Summary());
        $writer->writeObjectValue('description', $this->getDescription());
        $writer->writeCollectionOfObjectValues('exploits', $this->getExploits());
        $writer->writeBooleanValue('exploitsAvailable', $this->getExploitsAvailable());
        $writer->writeBooleanValue('hasChatter', $this->getHasChatter());
        $writer->writeDateTimeValue('lastModifiedDateTime', $this->getLastModifiedDateTime());
        $writer->writeIntegerValue('priorityScore', $this->getPriorityScore());
        $writer->writeDateTimeValue('publishedDateTime', $this->getPublishedDateTime());
        $writer->writeCollectionOfObjectValues('references', $this->getReferences());
        $writer->writeObjectValue('remediation', $this->getRemediation());
        $writer->writeEnumValue('severity', $this->getSeverity());
    }

    /**
     * Sets the activeExploitsObserved property value. Indicates whether this vulnerability has any known exploits associated to known bad actors.
     * @param bool|null $value Value to set for the activeExploitsObserved property.
    */
    public function setActiveExploitsObserved(?bool $value): void {
        $this->getBackingStore()->set('activeExploitsObserved', $value);
    }

    /**
     * Sets the articles property value. Articles related to this vulnerability.
     * @param array<Article>|null $value Value to set for the articles property.
    */
    public function setArticles(?array $value): void {
        $this->getBackingStore()->set('articles', $value);
    }

    /**
     * Sets the commonWeaknessEnumerationIds property value. Community-defined common weakness enumerations (CWE).
     * @param array<string>|null $value Value to set for the commonWeaknessEnumerationIds property.
    */
    public function setCommonWeaknessEnumerationIds(?array $value): void {
        $this->getBackingStore()->set('commonWeaknessEnumerationIds', $value);
    }

    /**
     * Sets the components property value. Components related to this vulnerability article.
     * @param array<VulnerabilityComponent>|null $value Value to set for the components property.
    */
    public function setComponents(?array $value): void {
        $this->getBackingStore()->set('components', $value);
    }

    /**
     * Sets the createdDateTime property value. The date and time when this vulnerability article was first created.
     * @param DateTime|null $value Value to set for the createdDateTime property.
    */
    public function setCreatedDateTime(?DateTime $value): void {
        $this->getBackingStore()->set('createdDateTime', $value);
    }

    /**
     * Sets the cvss2Summary property value. The cvss2Summary property
     * @param CvssSummary|null $value Value to set for the cvss2Summary property.
    */
    public function setCvss2Summary(?CvssSummary $value): void {
        $this->getBackingStore()->set('cvss2Summary', $value);
    }

    /**
     * Sets the cvss3Summary property value. The cvss3Summary property
     * @param CvssSummary|null $value Value to set for the cvss3Summary property.
    */
    public function setCvss3Summary(?CvssSummary $value): void {
        $this->getBackingStore()->set('cvss3Summary', $value);
    }

    /**
     * Sets the description property value. The description property
     * @param FormattedContent|null $value Value to set for the description property.
    */
    public function setDescription(?FormattedContent $value): void {
        $this->getBackingStore()->set('description', $value);
    }

    /**
     * Sets the exploits property value. Known exploits for this vulnerability.
     * @param array<Hyperlink>|null $value Value to set for the exploits property.
    */
    public function setExploits(?array $value): void {
        $this->getBackingStore()->set('exploits', $value);
    }

    /**
     * Sets the exploitsAvailable property value. Indicates whether this vulnerability has exploits in public sources (such as Packetstorm or Exploit-DB) online.
     * @param bool|null $value Value to set for the exploitsAvailable property.
    */
    public function setExploitsAvailable(?bool $value): void {
        $this->getBackingStore()->set('exploitsAvailable', $value);
    }

    /**
     * Sets the hasChatter property value. Indicates whether chatter about this vulnerability has been discovered online.
     * @param bool|null $value Value to set for the hasChatter property.
    */
    public function setHasChatter(?bool $value): void {
        $this->getBackingStore()->set('hasChatter', $value);
    }

    /**
     * Sets the lastModifiedDateTime property value. The date and time when this vulnerability article was most recently updated.
     * @param DateTime|null $value Value to set for the lastModifiedDateTime property.
    */
    public function setLastModifiedDateTime(?DateTime $value): void {
        $this->getBackingStore()->set('lastModifiedDateTime', $value);
    }

    /**
     * Sets the priorityScore property value. A unique algorithm that reflects the priority of a vulnerability based on the CVSS score, exploits, chatter, and linkage to malware. This property also evaluates the recency of these components so users can understand which vulnerability should be remediated first.
     * @param int|null $value Value to set for the priorityScore property.
    */
    public function setPriorityScore(?int $value): void {
        $this->getBackingStore()->set('priorityScore', $value);
    }

    /**
     * Sets the publishedDateTime property value. The date and time when this vulnerability article was published.
     * @param DateTime|null $value Value to set for the publishedDateTime property.
    */
    public function setPublishedDateTime(?DateTime $value): void {
        $this->getBackingStore()->set('publishedDateTime', $value);
    }

    /**
     * Sets the references property value. Reference links where further information can be learned about this vulnerability.
     * @param array<Hyperlink>|null $value Value to set for the references property.
    */
    public function setReferences(?array $value): void {
        $this->getBackingStore()->set('references', $value);
    }

    /**
     * Sets the remediation property value. Any known remediation steps.
     * @param FormattedContent|null $value Value to set for the remediation property.
    */
    public function setRemediation(?FormattedContent $value): void {
        $this->getBackingStore()->set('remediation', $value);
    }

    /**
     * Sets the severity property value. The severity property
     * @param VulnerabilitySeverity|null $value Value to set for the severity property.
    */
    public function setSeverity(?VulnerabilitySeverity $value): void {
        $this->getBackingStore()->set('severity', $value);
    }

}
