# (c) cavaliba.com - tests / loader csv no pipeline

import os
import tempfile

from django.test import TestCase

import app_home.cache as cache
from app_data.loader import load_file_csv
from tests.helper import add_schema


class TestLoaderCsvNoPipeline(TestCase):
    def setUp(self):
        cache.clear()

        add_schema(
            classname="csvtest",
            field_definition={
                "mystring": {"dataformat": "string", "displayname": "MyString"},
            },
        )
        add_schema(
            classname="csvtest2",
            field_definition={
                "mystring": {"dataformat": "string", "displayname": "MyString"},
            },
        )

    def _write_csv(self, content):
        fd, path = tempfile.mkstemp(suffix=".csv")
        with os.fdopen(fd, "w", encoding="utf-8") as f:
            f.write(content)
        return path

    def test_schema_name_param_used_as_fallback(self):
        """No pipeline, no per-row column: schema_name param supplies the classname."""

        path = self._write_csv("keyname,mystring\nrow1,hello\n")
        try:
            datalist = load_file_csv(filename=path, schema_name="csvtest")
        finally:
            os.remove(path)

        self.assertEqual(len(datalist), 1)
        self.assertEqual(datalist[0]["classname"], "csvtest")
        self.assertEqual(datalist[0]["keyname"], "row1")

    def test_row_schema_column_overrides_schema_name_param(self):
        """A per-row "schema" column wins over the schema_name fallback, and is
        renamed to "classname" (removed from the row dict)."""

        path = self._write_csv("keyname,schema,mystring\nrow1,csvtest2,hello\n")
        try:
            datalist = load_file_csv(filename=path, schema_name="csvtest")
        finally:
            os.remove(path)

        self.assertEqual(len(datalist), 1)
        self.assertEqual(datalist[0]["classname"], "csvtest2")
        self.assertNotIn("schema", datalist[0])

    def test_classname_column_is_not_a_resolution_source(self):
        """A "classname" column (as opposed to "schema") is not consulted; without a
        schema_name fallback, the row is skipped as a parse error."""

        path = self._write_csv("keyname,classname,mystring\nrow1,csvtest2,hello\n")
        errors = []
        try:
            datalist = load_file_csv(filename=path, errors=errors)
        finally:
            os.remove(path)

        self.assertEqual(datalist, [])
        self.assertEqual(len(errors), 1)
        self.assertEqual(errors[0]["row"], 1)

    def test_missing_classname_collected_not_aborted(self):
        """Rows with no resolvable classname are skipped and collected into errors,
        not raised as a hard failure; other rows in the same file are unaffected."""

        path = self._write_csv("keyname,mystring\nrow1,hello\nrow2,world\n")
        errors = []
        try:
            datalist = load_file_csv(filename=path, errors=errors)
        finally:
            os.remove(path)

        self.assertEqual(datalist, [])
        self.assertEqual(len(errors), 2)
        self.assertEqual(errors[0]["row"], 1)
        self.assertEqual(errors[1]["row"], 2)

    def test_missing_keyname_collected_not_aborted(self):
        """A row with no "keyname" column value is skipped and collected into errors."""

        path = self._write_csv("mystring\nhello\n")
        errors = []
        try:
            datalist = load_file_csv(filename=path, schema_name="csvtest", errors=errors)
        finally:
            os.remove(path)

        self.assertEqual(datalist, [])
        self.assertEqual(len(errors), 1)
        self.assertIn("keyname", errors[0]["message"])
