# -*- mode:python; coding:utf-8 -*-
# Copyright (c) 2020 IBM Corp. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#
#
####### DO NOT EDIT DO NOT EDIT DO NOT EDIT DO NOT EDIT DO NOT EDIT ######
#                                                                        #
#        This file is automatically generated by gen_oscal.py            #
#                                                                        #
####### DO NOT EDIT DO NOT EDIT DO NOT EDIT DO NOT EDIT DO NOT EDIT ######
#
#
from __future__ import annotations

import re
from datetime import datetime
from enum import Enum
from typing import Any, Dict, List, Optional, Union

from pydantic.v1 import AnyUrl, EmailStr, Extra, Field, conint, constr, validator

from trestle.core.base_model import OscalBaseModel
from trestle.oscal import OSCAL_VERSION_REGEX, OSCAL_VERSION
import trestle.oscal.common as common
from trestle.oscal.common import RelatedObservation
from trestle.oscal.common import TaskValidValues
from trestle.oscal.common import TokenDatatype
from trestle.oscal.common import RelatedObservation as RelatedObservation1


class LocalDefinitions(OscalBaseModel):
    """
    Allows components, and inventory-items to be defined within the POA&M for circumstances where no OSCAL-based SSP exists, or is not delivered with the POA&M.
    """

    class Config:
        extra = Extra.forbid

    components: Optional[List[common.SystemComponent]] = Field(None)
    inventory_items: Optional[List[common.InventoryItem]] = Field(None, alias='inventory-items')
    assessment_assets: Optional[common.AssessmentAssets] = Field(None, alias='assessment-assets')
    remarks: Optional[str] = None


class Origination(OscalBaseModel):
    """
    Identifies the source of the finding, such as a tool or person.
    """

    class Config:
        extra = Extra.forbid

    actors: List[common.OriginActor] = Field(...)


class RelatedFinding(OscalBaseModel):
    """
    Relates the finding to referenced finding(s).
    """

    class Config:
        extra = Extra.forbid

    finding_uuid: constr(
        regex=r'^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[45][0-9A-Fa-f]{3}-[89ABab][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}$'
    ) = Field(
        ...,
        alias='finding-uuid',
        description='A machine-oriented identifier reference to a finding defined in the list of findings.',
        title='Finding Universally Unique Identifier Reference'
    )


class PoamItem(OscalBaseModel):
    """
    Describes an individual POA&M item.
    """

    class Config:
        extra = Extra.forbid

    uuid: Optional[constr(
        regex=r'^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[45][0-9A-Fa-f]{3}-[89ABab][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}$'
    )] = Field(
        None,
        description=
        'A machine-oriented, globally unique identifier with instance scope that can be used to reference this POA&M item entry in this OSCAL instance. This UUID should be assigned per-subject, which means it should be consistently used to identify the same subject across revisions of the document.',
        title='POA&M Item Universally Unique Identifier'
    )
    title: str = Field(..., description='The title or name for this POA&M item .', title='POA&M Item Title')
    description: str = Field(
        ..., description='A human-readable description of POA&M item.', title='POA&M Item Description'
    )
    props: Optional[List[common.Property]] = Field(None)
    links: Optional[List[common.Link]] = Field(None)
    related_findings: Optional[List[RelatedFinding]] = Field(None, alias='related-findings')
    related_observations: Optional[List[common.RelatedObservation]] = Field(None, alias='related-observations')
    related_risks: Optional[List[common.RelatedRisk]] = Field(None, alias='related-risks')
    remarks: Optional[str] = None
    origins: Optional[List[Origination]] = Field(None)


class PlanOfActionAndMilestones(OscalBaseModel):
    """
    A plan of action and milestones which identifies initial and residual risks, deviations, and disposition, such as those required by FedRAMP.
    """

    class Config:
        extra = Extra.forbid

    uuid: constr(
        regex=r'^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[45][0-9A-Fa-f]{3}-[89ABab][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}$'
    ) = Field(
        ...,
        description=
        'A machine-oriented, globally unique identifier with instancescope that can be used to reference this POA&M instance in this OSCAL instance. This UUID should be assigned per-subject, which means it should be consistently used to identify the same subject across revisions of the document.',
        title='POA&M Universally Unique Identifier'
    )
    metadata: common.Metadata
    import_ssp: Optional[common.ImportSsp] = Field(None, alias='import-ssp')
    system_id: Optional[common.SystemId] = Field(None, alias='system-id')
    local_definitions: Optional[LocalDefinitions] = Field(None, alias='local-definitions')
    observations: Optional[List[common.Observation]] = Field(None)
    risks: Optional[List[common.Risk]] = Field(None)
    findings: Optional[List[common.Finding]] = Field(None)
    poam_items: List[PoamItem] = Field(..., alias='poam-items')
    back_matter: Optional[common.BackMatter] = Field(None, alias='back-matter')


class Model(OscalBaseModel):
    plan_of_action_and_milestones: PlanOfActionAndMilestones = Field(..., alias='plan-of-action-and-milestones')
