# (c) cavaliba.com - tests / loader utf-8 BOM handling

import io
import os
import tempfile

from django.test import TestCase

import app_home.cache as cache
from app_data.loader import load_file_csv, load_file_json, load_file_yaml


class TestLoaderBom(TestCase):
    """Files written by Windows editors start with a UTF-8 BOM. It must never
    reach the parsed data - on CSV it used to stick to the first column name
    ("﻿keyname"), so every row came back missing that column."""

    def setUp(self):
        cache.clear()

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

    def test_csv_bom_default_encoding(self):
        path = self._write("keyname,mystring\nrow1,hello\n", ".csv")
        try:
            datalist, err = load_file_csv(filename=path, csv_delimiter=",")
        finally:
            os.remove(path)

        self.assertIsNone(err)
        self.assertEqual(list(datalist[0].keys()), ["keyname", "mystring"])
        self.assertEqual(datalist[0]["keyname"], "row1")

    def test_csv_bom_explicit_utf8_encoding(self):
        path = self._write("keyname,mystring\nrow1,hello\n", ".csv")
        try:
            datalist, err = load_file_csv(filename=path, encoding="utf-8", csv_delimiter=",")
        finally:
            os.remove(path)

        self.assertIsNone(err)
        self.assertEqual(datalist[0]["keyname"], "row1")

    def test_csv_without_bom_still_works(self):
        path = self._write("keyname,mystring\nrow1,hello\n", ".csv", encoding="utf-8")
        try:
            datalist, err = load_file_csv(filename=path, csv_delimiter=",")
        finally:
            os.remove(path)

        self.assertIsNone(err)
        self.assertEqual(datalist[0]["keyname"], "row1")

    def test_csv_bom_on_a_caller_supplied_stream(self):
        source = io.StringIO("﻿keyname,mystring\nrow1,hello\n")
        datalist, err = load_file_csv(file=source, csv_delimiter=",")

        self.assertIsNone(err)
        self.assertEqual(datalist[0]["keyname"], "row1")

    def test_json_bom(self):
        path = self._write('[{"keyname": "row1"}]', ".json")
        try:
            datalist, err = load_file_json(filename=path)
        finally:
            os.remove(path)

        self.assertIsNone(err)
        self.assertEqual(datalist[0]["keyname"], "row1")

    def test_yaml_bom(self):
        path = self._write("- keyname: row1\n", ".yml")
        try:
            datalist, err = load_file_yaml(filename=path)
        finally:
            os.remove(path)

        self.assertIsNone(err)
        self.assertEqual(datalist[0]["keyname"], "row1")
