using System;

namespace pdinklag
{
    /// <summary>
    /// An asset address.
    /// </summary>
    [Serializable]
    public struct AssetAddress
    {
        private static readonly char SEPARATOR = '/';

        /// <summary>
        /// Implicitly converts a string to an asset address if applicable.
        /// </summary>
        /// <param name="address">the address string</param>
        public static implicit operator AssetAddress(string address) => new AssetAddress(address);

        public static bool operator ==(AssetAddress a, AssetAddress b) => a.Value == b.Value;
        public static bool operator !=(AssetAddress a, AssetAddress b) => a.Value != b.Value;

        // nb: no implicit bool conversion because we're extending BinaryReader / BinaryWriter

        /// <summary>
        /// An invalid address.
        /// </summary>
        public static AssetAddress None => new AssetAddress(string.Empty);

        /// <summary>
        /// Tests whether the address is valid (non-empty)
        /// </summary>
        public bool IsValid => !string.IsNullOrEmpty(Value);

        /// <summary>
        /// The address string.
        /// </summary>
        public string Value;

        /// <summary>
        /// Constructs an asset address.
        /// </summary>
        /// <param name="address">the address string</param>
        public AssetAddress(string address)
        {
            Value = address ?? string.Empty;
        }

        /// <summary>
        /// Combines this address with another address separated by a slash.
        /// </summary>
        /// <param name="suffix">the suffix</param>
        /// <returns></returns>
        public readonly AssetAddress Combine(AssetAddress suffix) => Value + SEPARATOR + suffix.Value;

        /// <summary>
        /// Returns the address up to the first separator (slash), or the entire address if there is no separator.
        /// </summary>
        /// <returns></returns>
        public AssetAddress Prefix()
        {
            var slashPos = Value.IndexOf(SEPARATOR);
            if (slashPos >= 0)
            {
                return Value[..slashPos];
            }
            else
            {
                return Value;
            }
        }


        /// <summary>
        /// Returns the address starting after the first separator (slash), or the entire address if there is no separator.
        /// </summary>
        /// <returns></returns>
        public AssetAddress Suffix()
        {
            var slashPos = Value.IndexOf(SEPARATOR);
            if (slashPos >= 0 && slashPos < Value.Length - 1)
            {
                return Value[(slashPos + 1)..];
            }
            else
            {
                return Value;
            }
        }
        public override int GetHashCode() => Value.GetHashCode();
        public override bool Equals(object obj) => obj is AssetAddress address && Value == address.Value;
        public override string ToString() => Value;
        public string ToLocalizationKey() => Value.Replace(SEPARATOR, '.');
    }
}
