#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace Google.Protobuf
{
    /// <summary>
    /// Immutable array of bytes.
    /// TODO(jonskeet): Implement the common collection interfaces?
    /// </summary>
    public sealed class ByteString : IEnumerable<byte>, IEquatable<ByteString>
    {
        private static readonly ByteString empty = new ByteString(new byte[0]);

        private readonly byte[] bytes;

        /// <summary>
        /// Unsafe operations that can cause IO Failure and/or other catestrophic side-effects.
        /// </summary>
        public static class Unsafe
        {
            /// <summary>
            /// Constructs a new ByteString from the given byte array. The array is
            /// *not* copied, and must not be modified after this constructor is called.
            /// </summary>
            public static ByteString FromBytes(byte[] bytes)
            {
                return new ByteString(bytes);
            }

            /// <summary>
            /// Provides direct, unrestricted access to the bytes contained in this instance.
            /// You must not modify or resize the byte array returned by this method.
            /// </summary>
            public static byte[] GetBuffer(ByteString bytes)
            {
                return bytes.bytes;
            }
        }

        /// <summary>
        /// Internal use only.  Ensure that the provided array is not mutated and belongs to this instance.
        /// </summary>
        internal static ByteString AttachBytes(byte[] bytes)
        {
            return new ByteString(bytes);
        }

        /// <summary>
        /// Constructs a new ByteString from the given byte array. The array is
        /// *not* copied, and must not be modified after this constructor is called.
        /// </summary>
        private ByteString(byte[] bytes)
        {
            this.bytes = bytes;
        }

        /// <summary>
        /// Returns an empty ByteString.
        /// </summary>
        public static ByteString Empty
        {
            get { return empty; }
        }

        /// <summary>
        /// Returns the length of this ByteString in bytes.
        /// </summary>
        public int Length
        {
            get { return bytes.Length; }
        }

        public bool IsEmpty
        {
            get { return Length == 0; }
        }

        public byte[] ToByteArray()
        {
            return (byte[]) bytes.Clone();
        }

        public string ToBase64()
        {
            return Convert.ToBase64String(bytes);
        }

        /// <summary>
        /// Constructs a ByteString from the Base64 Encoded String.
        /// </summary>
        public static ByteString FromBase64(string bytes)
        {
            // By handling the empty string explicitly, we not only optimize but we fix a
            // problem on CF 2.0. See issue 61 for details.
            return bytes == "" ? Empty : new ByteString(Convert.FromBase64String(bytes));
        }

        /// <summary>
        /// Constructs a ByteString from the given array. The contents
        /// are copied, so further modifications to the array will not
        /// be reflected in the returned ByteString.
        /// </summary>
        public static ByteString CopyFrom(params byte[] bytes)
        {
            return new ByteString((byte[]) bytes.Clone());
        }

        /// <summary>
        /// Constructs a ByteString from a portion of a byte array.
        /// </summary>
        public static ByteString CopyFrom(byte[] bytes, int offset, int count)
        {
            byte[] portion = new byte[count];
            ByteArray.Copy(bytes, offset, portion, 0, count);
            return new ByteString(portion);
        }

        /// <summary>
        /// Creates a new ByteString by encoding the specified text with
        /// the given encoding.
        /// </summary>
        public static ByteString CopyFrom(string text, Encoding encoding)
        {
            return new ByteString(encoding.GetBytes(text));
        }

        /// <summary>
        /// Creates a new ByteString by encoding the specified text in UTF-8.
        /// </summary>
        public static ByteString CopyFromUtf8(string text)
        {
            return CopyFrom(text, Encoding.UTF8);
        }

        /// <summary>
        /// Retuns the byte at the given index.
        /// </summary>
        public byte this[int index]
        {
            get { return bytes[index]; }
        }

        public string ToString(Encoding encoding)
        {
            return encoding.GetString(bytes, 0, bytes.Length);
        }

        public string ToStringUtf8()
        {
            return ToString(Encoding.UTF8);
        }

        public IEnumerator<byte> GetEnumerator()
        {
            return ((IEnumerable<byte>) bytes).GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        /// <summary>
        /// Creates a CodedInputStream from this ByteString's data.
        /// </summary>
        public CodedInputStream CreateCodedInput()
        {
            // We trust CodedInputStream not to reveal the provided byte array or modify it
            return CodedInputStream.CreateInstance(bytes);
        }

        public static bool operator ==(ByteString lhs, ByteString rhs)
        {
            if (ReferenceEquals(lhs, rhs))
            {
                return true;
            }
            if (ReferenceEquals(lhs, null))
            {
                return false;
            }
            return lhs.Equals(rhs);
        }

        public static bool operator !=(ByteString lhs, ByteString rhs)
        {
            return !(lhs == rhs);
        }

        // TODO(jonskeet): CopyTo if it turns out to be required

        public override bool Equals(object obj)
        {
            ByteString other = obj as ByteString;
            if (obj == null)
            {
                return false;
            }
            return Equals(other);
        }

        public override int GetHashCode()
        {
            int ret = 23;
            foreach (byte b in bytes)
            {
                ret = (ret << 8) | b;
            }
            return ret;
        }

        public bool Equals(ByteString other)
        {
            if (other.bytes.Length != bytes.Length)
            {
                return false;
            }
            for (int i = 0; i < bytes.Length; i++)
            {
                if (other.bytes[i] != bytes[i])
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// Used internally by CodedOutputStream to avoid creating a copy for the write
        /// </summary>
        internal void WriteRawBytesTo(CodedOutputStream outputStream)
        {
            outputStream.WriteRawBytes(bytes, 0, bytes.Length);
        }

        /// <summary>
        /// Copies the entire byte array to the destination array provided at the offset specified.
        /// </summary>
        public void CopyTo(byte[] array, int position)
        {
            ByteArray.Copy(bytes, 0, array, position, bytes.Length);
        }

        /// <summary>
        /// Writes the entire byte array to the provided stream
        /// </summary>
        public void WriteTo(Stream outputStream)
        {
            outputStream.Write(bytes, 0, bytes.Length);
        }
    }
}