#   Copyright ETH 2025 Zürich, Scientific IT Services
#
#   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
#
#        http://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.
#
import time
import uuid

import pytest


def test_new_object_property_type(space):
    o = space.openbis

    current_date = time.strftime("%Y-%m-%d").lower()

    # Create custom SAMPLE property type accepting ALL sample types
    property_type_code = "test_property_type_" + current_date + "_" + str(uuid.uuid4())
    pt = o.new_property_type(
        code=property_type_code,
        label='custom property of data type date',
        description='custom property created in unit test',
        dataType='SAMPLE',
    )
    pt.save()

    assert pt.code == property_type_code.upper()
    assert pt.dataType == 'SAMPLE'
    assert pt.sampleType == '(ALL)'


def test_new_object_property_type_with_sample_type(space):
    o = space.openbis

    current_date = time.strftime("%Y-%m-%d").lower()

    sample_type_code = "test_sample_type_" + current_date + "_" + str(uuid.uuid4())
    sample_type = o.new_sample_type(
        code=sample_type_code,
        generatedCodePrefix="S",
        autoGeneratedCode=True,
        listable=True,
    )
    sample_type.save()

    # Create custom SAMPLE property type accepting a single sample type
    property_type_code = "test_property_type_" + current_date + "_" + str(uuid.uuid4())
    pt = o.new_property_type(
        code=property_type_code,
        label='custom property of data type date',
        description='custom property created in unit test',
        dataType='SAMPLE',
        sampleType=sample_type.code,
    )
    pt.save()

    assert pt.code == property_type_code.upper()
    assert pt.dataType == 'SAMPLE'
    assert pt.sampleType == sample_type.code


def test_get_sample_type_from_property_assignment(space):
    o = space.openbis

    current_date = time.strftime("%Y-%m-%d").lower()

    sample_type_code = "test_sample_type_" + current_date + "_" + str(uuid.uuid4())
    sample_type = o.new_sample_type(
        code=sample_type_code,
        generatedCodePrefix="S",
        autoGeneratedCode=True,
        listable=True,
    )
    sample_type.save()

    property_type_code = "test_property_type_" + current_date + "_" + str(uuid.uuid4())
    pt = o.new_property_type(
        code=property_type_code,
        label='custom property of data type date',
        description='custom property created in unit test',
        dataType='SAMPLE',
        sampleType=sample_type.code,
    )
    pt.save()

    sample_type.assign_property(pt)
    sample_type.save()


    ps = sample_type.get_property_assignments()

    assert len(ps.df) == 1

    property_type = ps[0].get_property_type()
    assert property_type.code.lower() == property_type_code
    assert property_type.dataType == 'SAMPLE'
    assert property_type.sampleType == sample_type.code


def test_get_sample_type_all_from_property_assignment(space):
    o = space.openbis

    current_date = time.strftime("%Y-%m-%d").lower()

    sample_type_code = "test_sample_type_" + current_date + "_" + str(uuid.uuid4())
    sample_type = o.new_sample_type(
        code=sample_type_code,
        generatedCodePrefix="S",
        autoGeneratedCode=True,
        listable=True,
    )
    sample_type.save()

    property_type_code = "test_property_type_" + current_date + "_" + str(uuid.uuid4())
    pt = o.new_property_type(
        code=property_type_code,
        label='custom property of data type date',
        description='custom property created in unit test',
        dataType='SAMPLE',
    )
    pt.save()

    sample_type.assign_property(pt)
    sample_type.save()


    ps = sample_type.get_property_assignments()

    assert len(ps.df) == 1

    property_type = ps[0].get_property_type()
    assert property_type.code.lower() == property_type_code
    assert property_type.dataType == 'SAMPLE'
    assert property_type.sampleType == '(ALL)'


def test_get_vocabulary_code_from_property_assignment(space):
    o = space.openbis

    current_date = time.strftime("%Y-%m-%d").lower()

    voc_code = 'test_voc_' + current_date + "_" + str(uuid.uuid4())

    voc = o.new_vocabulary(
        code=voc_code,
        description='description of vocabulary',
        urlTemplate='https://ethz.ch',
        terms=[
            {"code": 'term_code1', "label": "term_label1", "description": "term_description1"},
            {"code": 'term_code2', "label": "term_label2", "description": "term_description2"},
            {"code": 'term_code3', "label": "term_label3", "description": "term_description3"}
        ],
        chosenFromList=False
    )
    voc.save()

    sample_type_code = "test_vocabulary_" + current_date + "_" + str(uuid.uuid4())
    sample_type = o.new_sample_type(
        code=sample_type_code,
        generatedCodePrefix="S",
        autoGeneratedCode=True,
        listable=True,
    )
    sample_type.save()

    property_type_code = "test_property_type_" + current_date + "_" + str(uuid.uuid4())
    pt = o.new_property_type(
        code=property_type_code,
        label='custom property of data type date',
        description='custom property created in unit test',
        dataType='CONTROLLEDVOCABULARY',
        vocabulary=voc_code
    )
    pt.save()

    sample_type.assign_property(pt)
    sample_type.save()


    ps = sample_type.get_property_assignments()

    assert len(ps.df) == 1

    property_type = ps[0].get_property_type()
    assert property_type.code.lower() == property_type_code
    assert property_type.dataType == 'CONTROLLEDVOCABULARY'
    assert property_type.vocabulary == voc_code.upper()