using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using CsvHelper;

using Hatfield.EnviroData.DataAcquisition;

namespace Hatfield.EnviroData.DataAcquisition.CSV.Parsers
{
    public class CellParser : IParser
    {
        private IParserFactory _parserFactory;

        public CellParser(IParserFactory parserFactory)
        {
            _parserFactory = parserFactory;
        }

        public IResult Parse(IDataToImport dataToImport, IDataSourceLocation dataSourceLocation, Type type)
        {
            if (!(dataSourceLocation is CSVDataSourceLocation))
            {
                return new ParsingResult(ResultLevel.FATAL, dataSourceLocation.GetType().ToString() + " is not supported by CSV Cell Parser", null, null);
            }

            if (!(dataToImport is CSVDataToImport))
            {
                return new ParsingResult(ResultLevel.FATAL, dataToImport.GetType().ToString() + " is not supported by CSV Cell Parser", null, null);
            }


            var castedDataToImport = dataToImport as CSVDataToImport;
            var castedDataSourceLocation = dataSourceLocation as CSVDataSourceLocation;

            try
            {
                var rawData = GetRawDataValue(castedDataSourceLocation, castedDataToImport);
                var parsedValue = ParseRawValue(type, rawData);

                return new ParsingResult(ResultLevel.INFO, "Parsing value successfully", parsedValue, castedDataSourceLocation);
            }
            catch (IndexOutOfRangeException)
            {
                return new ParsingResult(ResultLevel.FATAL, "Index is out of range", null, castedDataSourceLocation);
            }
        }

        private string GetRawDataValue(CSVDataSourceLocation location, CSVDataToImport csvDataToImport)
        {
            var data = csvDataToImport.Data as string[][];
            return data[location.Row][location.Column];
        }

        private object ParseRawValue(Type type, string rawValue)
        {
            var valueParser = _parserFactory.GetValueParser(type);

            var parsedValue = valueParser.Parse(rawValue);

            return parsedValue;
        }
    }
}