using System;
using System.Collections.Generic;
using System.Data;
using System.IO;

namespace KarleyLibrary.Erweiterungen
{
    public class CSVReader
    {
        public static IEnumerable<T> Read<T>(TextReader reader, char delimiter = ';', bool respectStringifications = true)
        {
            string? attributeLine = reader.ReadLine();
            if (!String.IsNullOrWhiteSpace(attributeLine))
            {
                string[] attributes = AdvancedSplit(attributeLine, delimiter, respectStringifications);
                DataTable gen = ArrayToTable(attributes);
                string? line;
                while ((line = reader.ReadLine()) != null)
                {
                    if (!String.IsNullOrWhiteSpace(line))
                    {

                        string[] values = AdvancedSplit(line,delimiter,true);

                        DataRow row = gen.NewRow();

                        for (int i = 0; i < values.Length; i++)
                        {
                            string attr = attributes[i];
                            if (String.IsNullOrWhiteSpace(attr))
                                continue;
                            row[attr] = values[i];
                        }
                        yield return ObjectErweiterung.DataRowZuObjekt(ObjectErweiterung.InstanceFromType<T>(), row);
                    }
                }
            }
        }

        public static IEnumerable<T> Read<T>(string file, char delimiter = ';')
        {
            using (StreamReader streamReader = new StreamReader(file))
            {
                foreach (T res in Read<T>(streamReader))
                {
                    yield return res;
                }
            }

        }

        private static string[] AdvancedSplit(string line, char delimiter, bool respectStringifications)
        {
            List<string> attributes = new List<string>();
            string tmpName = String.Empty;
            bool stringificationFlag = false;
            foreach (char c in line)
            {
                if (respectStringifications)
                {
                    if (stringificationFlag)
                    {
                        if (c == '"')
                        {
                            stringificationFlag = false;
                            continue;
                        }
                    }
                    else
                    {
                        if (c == '"')
                        {
                            stringificationFlag = true;
                            continue;
                        }

                    }
                }


                if (c == delimiter)
                {
                    if (stringificationFlag && respectStringifications)
                    {
                        tmpName += c;
                    }
                    else
                    {                                                
                        attributes.Add(tmpName);                        
                        tmpName = String.Empty;
                        stringificationFlag = false;
                    }
                    
                }
                else
                {
                    tmpName += c;
                }

            }
            return attributes.ToArray();
        }

        public static DataTable ArrayToTable(string[] columns)
        {
            DataTable data = new DataTable("Data");
            foreach (string col in columns)
            {
                if (String.IsNullOrWhiteSpace(col))
                    continue;
                DataColumn c = new DataColumn()
                {
                    DataType = typeof(string),
                    ColumnName = col,
                };
                data.Columns.Add(c);
            }
            return data;
        }
    }
}
