# -*- 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 AssessmentAssets
from trestle.oscal.common import Observation
from trestle.oscal.common import RelatedObservation
from trestle.oscal.common import SystemComponent
from trestle.oscal.common import TaskValidValues
from trestle.oscal.common import TokenDatatype


class LocalDefinitions1(OscalBaseModel):
    """
    Used to define data objects that are used in the assessment plan, that do not appear in the referenced SSP.
    """

    class Config:
        extra = Extra.forbid

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


class LocalDefinitions(OscalBaseModel):
    """
    Used to define data objects that are used in the assessment plan, that do not appear in the referenced SSP.
    """

    class Config:
        extra = Extra.forbid

    objectives_and_methods: Optional[List[common.LocalObjective]] = Field(None, alias='objectives-and-methods')
    activities: Optional[List[common.Activity]] = Field(None)
    remarks: Optional[str] = None


class ImportAp(OscalBaseModel):
    """
    Used by assessment-results to import information about the original plan for assessing the system.
    """

    class Config:
        extra = Extra.forbid

    href: str = Field(
        ...,
        description='A resolvable URL reference to the assessment plan governing the assessment activities.',
        title='Assessment Plan Reference'
    )
    remarks: Optional[str] = None


class Entry1(OscalBaseModel):
    """
    Identifies the result of an action and/or task that occurred as part of executing an assessment plan or an assessment event that occurred in producing the assessment results.
    """

    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 cross-instance scope that can be used to reference an assessment event in this or other OSCAL instances. The locally defined UUID of the assessment log entry can be used to reference the data item locally or globally (e.g., in an imported 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='Assessment Log Entry Universally Unique Identifier',
    )
    title: Optional[str] = Field(None, description='The title for this event.', title='Action Title')
    description: Optional[str] = Field(
        None, description='A human-readable description of this event.', title='Action Description'
    )
    start: datetime = Field(..., description='Identifies the start date and time of an event.', title='Start')
    end: Optional[datetime] = Field(
        None,
        description=
        'Identifies the end date and time of an event. If the event is a point in time, the start and end will be the same date and time.',
        title='End'
    )
    props: Optional[List[common.Property]] = Field(None)
    links: Optional[List[common.Link]] = Field(None)
    logged_by: Optional[List[common.LoggedBy]] = Field(None, alias='logged-by')
    related_tasks: Optional[List[common.RelatedTask]] = Field(None, alias='related-tasks')
    remarks: Optional[str] = None


class Attestation(OscalBaseModel):
    """
    A set of textual statements, typically written by the assessor.
    """

    class Config:
        extra = Extra.forbid

    responsible_parties: Optional[List[common.ResponsibleParty]] = Field(None, alias='responsible-parties')
    parts: List[common.AssessmentPart] = Field(...)


class AssessmentLog(OscalBaseModel):
    """
    A log of all assessment-related actions taken.
    """

    class Config:
        extra = Extra.forbid

    entries: List[Entry1] = Field(...)


class Result(OscalBaseModel):
    """
    Used by the assessment results and POA&M. In the assessment results, this identifies all of the assessment observations and findings, initial and residual risks, deviations, and disposition. In the POA&M, this identifies initial and residual risks, deviations, and disposition.
    """

    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 cross-instance scope that can be used to reference this set of results in this or other OSCAL instances. The locally defined UUID of the assessment result can be used to reference the data item locally or globally (e.g., in an imported 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='Results Universally Unique Identifier',
    )
    title: str = Field(..., description='The title for this set of results.', title='Results Title')
    description: str = Field(
        ..., description='A human-readable description of this set of test results.', title='Results Description'
    )
    start: datetime = Field(
        ...,
        description='Date/time stamp identifying the start of the evidence collection reflected in these results.',
        title='start field'
    )
    end: Optional[datetime] = Field(
        None,
        description=
        'Date/time stamp identifying the end of the evidence collection reflected in these results. In a continuous motoring scenario, this may contain the same value as start if appropriate.',
        title='end field'
    )
    props: Optional[List[common.Property]] = Field(None)
    links: Optional[List[common.Link]] = Field(None)
    local_definitions: Optional[LocalDefinitions1] = Field(
        None,
        alias='local-definitions',
        description=
        'Used to define data objects that are used in the assessment plan, that do not appear in the referenced SSP.',
        title='Local Definitions'
    )
    reviewed_controls: common.ReviewedControls = Field(..., alias='reviewed-controls')
    attestations: Optional[List[Attestation]] = Field(None)
    assessment_log: Optional[AssessmentLog] = Field(
        None,
        alias='assessment-log',
        description='A log of all assessment-related actions taken.',
        title='Assessment Log'
    )
    observations: Optional[List[common.Observation]] = Field(None)
    risks: Optional[List[common.Risk]] = Field(None)
    findings: Optional[List[common.Finding]] = Field(None)
    remarks: Optional[str] = None


class AssessmentResults(OscalBaseModel):
    """
    Security assessment results, such as those provided by a FedRAMP assessor in the FedRAMP Security Assessment Report.
    """

    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 cross-instance scope that can be used to reference this assessment results instance in this or other OSCAL instances. The locally defined UUID of the assessment result can be used to reference the data item locally or globally (e.g., in an imported 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='Assessment Results Universally Unique Identifier',
    )
    metadata: common.Metadata
    import_ap: ImportAp = Field(..., alias='import-ap')
    local_definitions: Optional[LocalDefinitions] = Field(
        None,
        alias='local-definitions',
        description=
        'Used to define data objects that are used in the assessment plan, that do not appear in the referenced SSP.',
        title='Local Definitions'
    )
    results: List[Result] = Field(...)
    back_matter: Optional[common.BackMatter] = Field(None, alias='back-matter')


class Model(OscalBaseModel):
    assessment_results: AssessmentResults = Field(..., alias='assessment-results')
