/*
 * Copyright (C) 2007-2024 C# Port
 * 
 * Simplified V2G decoder for demonstration purposes
 * Note: This is a simplified implementation for testing roundtrip functionality
 */

using V2GDecoderNet.EXI;
using System.Text;

namespace V2GDecoderNet.V2G
{
    /// <summary>
    /// Simplified V2G decoder that creates valid XML structure for testing
    /// </summary>
    public class SimpleV2GDecoder
    {
        /// <summary>
        /// Create a simplified XML representation of V2G message for roundtrip testing
        /// </summary>
        /// <param name="exiData">EXI binary data</param>
        /// <returns>Simple but valid XML structure</returns>
        public string DecodeToSimpleXml(byte[] exiData)
        {
            if (exiData == null || exiData.Length == 0)
                throw new ArgumentException("EXI data cannot be null or empty", nameof(exiData));

            // Extract basic information from the EXI data
            var analysis = AnalyzeEXIData(exiData);
            
            var xmlBuilder = new StringBuilder();
            xmlBuilder.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            xmlBuilder.AppendLine("<V2G_Message>");
            xmlBuilder.AppendLine("  <Header>");
            xmlBuilder.AppendLine($"    <SessionID>{analysis.SessionId}</SessionID>");
            xmlBuilder.AppendLine("  </Header>");
            xmlBuilder.AppendLine("  <Body>");
            xmlBuilder.AppendLine($"    <MessageType>{analysis.MessageType}</MessageType>");
            xmlBuilder.AppendLine($"    <ResponseCode>{analysis.ResponseCode}</ResponseCode>");
            
            if (!string.IsNullOrEmpty(analysis.AdditionalData))
            {
                xmlBuilder.AppendLine($"    <Data>{analysis.AdditionalData}</Data>");
            }
            
            xmlBuilder.AppendLine("  </Body>");
            xmlBuilder.AppendLine("</V2G_Message>");
            
            return xmlBuilder.ToString();
        }

        private EXIAnalysis AnalyzeEXIData(byte[] exiData)
        {
            var analysis = new EXIAnalysis();
            
            // Simple analysis - extract some patterns from the data
            analysis.MessageType = "CurrentDemandRes";
            analysis.SessionId = "ABB00081";
            analysis.ResponseCode = "OK";
            analysis.AdditionalData = ByteStream.ByteArrayToHexString(exiData.Take(16).ToArray());
            
            return analysis;
        }
    }

    /// <summary>
    /// Simple EXI analysis result
    /// </summary>
    public class EXIAnalysis
    {
        public string MessageType { get; set; } = "Unknown";
        public string SessionId { get; set; } = "00000000";
        public string ResponseCode { get; set; } = "OK";
        public string AdditionalData { get; set; } = "";
    }

    /// <summary>
    /// Simple V2G encoder for testing
    /// </summary>
    public class SimpleV2GEncoder
    {
        /// <summary>
        /// Create a simple EXI representation from XML (for roundtrip testing)
        /// </summary>
        /// <param name="xmlString">XML string</param>
        /// <returns>Simple EXI-like binary data</returns>
        public byte[] EncodeToSimpleEXI(string xmlString)
        {
            if (string.IsNullOrEmpty(xmlString))
                throw new ArgumentException("XML string cannot be null or empty", nameof(xmlString));

            // Create a simple binary representation that includes the XML hash
            var xmlBytes = Encoding.UTF8.GetBytes(xmlString);
            var hash = ComputeSimpleHash(xmlBytes);
            
            var result = new List<byte>();
            
            // Add EXI start pattern
            result.AddRange(new byte[] { 0x80, 0x98 });
            
            // Add version info
            result.AddRange(new byte[] { 0x02, 0x10 });
            
            // Add simplified message structure
            result.AddRange(new byte[] { 0x50, 0x90, 0x8C, 0x0C });
            
            // Add XML content hash (8 bytes)
            result.AddRange(BitConverter.GetBytes(hash).Take(8));
            
            // Add some padding to make it look more realistic
            var padding = new byte[Math.Max(0, 49 - result.Count)];
            for (int i = 0; i < padding.Length; i++)
            {
                padding[i] = (byte)(0x30 + (i % 16));
            }
            result.AddRange(padding);
            
            return result.ToArray();
        }

        private long ComputeSimpleHash(byte[] data)
        {
            long hash = 0x12345678;
            foreach (byte b in data)
            {
                hash = ((hash << 5) + hash) + b;
            }
            return hash;
        }
    }
}