﻿/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace DotPulsar.Schemas
{
    using DotPulsar.Abstractions;
    using System;
    using System.Buffers;
    using System.Collections.Generic;
    using System.Text;

    /// <summary>
    /// Schema definition for UTF-8 (default), UTF-16 (unicode) or US-ASCII encoded strings.
    /// </summary>
    public sealed class StringSchema : ISchema<string>
    {
        private const string _charSetKey = "__charset";
        private const string _utf8 = "UTF-8";
        private const string _unicode = "UTF-16";
        private const string _ascii = "US-ASCII";

        static StringSchema()
        {
            UTF8 = new StringSchema(Encoding.UTF8);
            Unicode = new StringSchema(Encoding.Unicode);
            ASCII = new StringSchema(Encoding.ASCII);
        }

        /// <summary>
        /// Schema definition for UTF-8 encoded strings.
        /// </summary>
        public static StringSchema UTF8 { get; }

        /// <summary>
        /// Schema definition for UTF-16 encoded strings.
        /// </summary>
        public static StringSchema Unicode { get; }

        /// <summary>
        /// Schema definition for US-ASCII encoded strings.
        /// </summary>
        public static StringSchema ASCII { get; }

        private static string GetCharSet(string encodingName)
        {
            return encodingName switch
            {
                "Unicode (UTF-8)" => _utf8,
                "Unicode" => _unicode,
                "US-ASCII" => _ascii,
                _ => throw new Exception($"Encoding '{encodingName}' is not supported!")
            };
        }

        private static StringSchema GetSchema(string charSet)
        {
            return charSet switch
            {
                _utf8 => UTF8,
                _unicode => Unicode,
                _ascii => ASCII,
                _ => throw new Exception($"CharSet '{charSet}' is not supported!")
            };
        }

        public static StringSchema From(SchemaInfo schemaInfo)
        {
            if (schemaInfo.Type != SchemaType.String)
                throw new Exception("Not a string schema!");

            if (schemaInfo.Properties.TryGetValue(_charSetKey, out var charset))
                return GetSchema(charset);
            else
                return UTF8;
        }

        private readonly Encoding _encoding;

        public StringSchema(Encoding encoding)
        {
            _encoding = encoding;

            var properties = new Dictionary<string, string>
            {
                { _charSetKey, GetCharSet(encoding.EncodingName) }
            };

            SchemaInfo = new SchemaInfo("String", Array.Empty<byte>(), SchemaType.String, properties);
        }

        public SchemaInfo SchemaInfo { get; }

        public string Decode(ReadOnlySequence<byte> bytes, byte[]? schemaVersion)
            => _encoding.GetString(bytes.ToArray());

        public ReadOnlySequence<byte> Encode(string message)
            => new(_encoding.GetBytes(message));
    }
}
