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

import os
import tempfile

import yaml
from django.test import TestCase

import app_home.cache as cache
from app_data.loader import load_broker, load_file_csv
from app_data.pipeline import Pipeline
from tests.helper import add_schema


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

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

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

    def test_load_file_csv_uses_explicit_delimiter_only(self):
        """load_file_csv no longer reads any config from a Pipeline, and no longer
        resolves a fallback classname itself - csv_delimiter passed explicitly is
        the only config source now."""

        path = self._write_csv("mykey;mystring\nabc;hello\n")
        try:
            datalist, err = load_file_csv(filename=path, csv_delimiter=";")
        finally:
            os.remove(path)

        self.assertEqual(len(datalist), 1)
        self.assertEqual(datalist[0]["mystring"], "hello")
        # no "schema"/"keyname" column in this CSV - neither is resolved here
        self.assertNotIn("classname", datalist[0])
        self.assertNotIn("keyname", datalist[0])

    def test_load_file_csv_row_without_classname_flows_through(self):
        """A row with no "schema" column still comes back from load_file_csv (no
        early reject) - only load_broker() rejects it."""

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

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

        result = load_broker(datalist=datalist, aaa={"perms": ["p_data_admin"]})
        self.assertEqual(result["count_ko"], 1)
        self.assertIn("missing classname", result["errors"][0])

    def test_pipeline_content_is_a_flat_rule_list(self):
        """A _pipeline instance's "content" field is directly the list of rules -
        no "tasks:" wrapper key."""

        datalist = yaml.safe_load("""
            - classname: _pipeline
              keyname: pipeline_flat
              displayname: pipeline_flat
              is_enabled: True
              content: |
                    - field_noop: ['']
            """)
        load_broker(datalist=datalist, aaa={"perms": ["p_pipeline_create"]})

        p = Pipeline.from_name("pipeline_flat")
        self.assertIsNotNone(p)
        self.assertEqual(len(p.rules), 1)
        self.assertFalse(hasattr(p, "csv_delimiter"))
        self.assertFalse(hasattr(p, "encoding"))
        self.assertFalse(hasattr(p, "keyfield"))
        self.assertFalse(hasattr(p, "classname"))
