﻿#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;

namespace Google.Protobuf
{
    internal sealed class JsonToken : IEquatable<JsonToken>
    {
        // Tokens with no value can be reused.
        private static readonly JsonToken _true = new JsonToken(TokenType.True);
        private static readonly JsonToken _false = new JsonToken(TokenType.False);
        private static readonly JsonToken _null = new JsonToken(TokenType.Null);
        private static readonly JsonToken startObject = new JsonToken(TokenType.StartObject);
        private static readonly JsonToken endObject = new JsonToken(TokenType.EndObject);
        private static readonly JsonToken startArray = new JsonToken(TokenType.StartArray);
        private static readonly JsonToken endArray = new JsonToken(TokenType.EndArray);
        private static readonly JsonToken endDocument = new JsonToken(TokenType.EndDocument);

        internal static JsonToken Null { get { return _null; } }
        internal static JsonToken False { get { return _false; } }
        internal static JsonToken True { get { return _true; } }
        internal static JsonToken StartObject{ get { return startObject; } }
        internal static JsonToken EndObject { get { return endObject; } }
        internal static JsonToken StartArray { get { return startArray; } }
        internal static JsonToken EndArray { get { return endArray; } }
        internal static JsonToken EndDocument { get { return endDocument; } }

        internal static JsonToken Name(string name)
        {
            return new JsonToken(TokenType.Name, stringValue: name);
        }

        internal static JsonToken Value(string value)
        {
            return new JsonToken(TokenType.StringValue, stringValue: value);
        }

        internal static JsonToken Value(double value)
        {
            return new JsonToken(TokenType.Number, numberValue: value);
        }

        internal enum TokenType
        {
            Null,
            False,
            True,
            StringValue,
            Number,
            Name,
            StartObject,
            EndObject,
            StartArray,
            EndArray,
            EndDocument
        }

        // A value is a string, number, array, object, null, true or false
        // Arrays and objects have start/end
        // A document consists of a value
        // Objects are name/value sequences.

        private readonly TokenType type;
        private readonly string stringValue;
        private readonly double numberValue;

        internal TokenType Type { get { return type; } }
        internal string StringValue { get { return stringValue; } }
        internal double NumberValue { get { return numberValue; } }

        private JsonToken(TokenType type, string stringValue = null, double numberValue = 0)
        {
            this.type = type;
            this.stringValue = stringValue;
            this.numberValue = numberValue;
        }

        public override bool Equals(object obj)
        {
            return Equals(obj as JsonToken);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                int hash = 17;
                hash = hash * 31 + (int) type;
                hash = hash * 31 + stringValue == null ? 0 : stringValue.GetHashCode();
                hash = hash * 31 + numberValue.GetHashCode();
                return hash;
            }
        }

        public override string ToString()
        {
            switch (type)
            {
                case TokenType.Null:
                    return "null";
                case TokenType.True:
                    return "true";
                case TokenType.False:
                    return "false";
                case TokenType.Name:
                    return "name (" + stringValue + ")";
                case TokenType.StringValue:
                    return "value (" + stringValue + ")";
                case TokenType.Number:
                    return "number (" + numberValue + ")";
                case TokenType.StartObject:
                    return "start-object";
                case TokenType.EndObject:
                    return "end-object";
                case TokenType.StartArray:
                    return "start-array";
                case TokenType.EndArray:
                    return "end-array";
                case TokenType.EndDocument:
                    return "end-document";
                default:
                    throw new InvalidOperationException("Token is of unknown type " + type);
            }
        }

        public bool Equals(JsonToken other)
        {
            if (ReferenceEquals(other, null))
            {
                return false;
            }
            // Note use of other.numberValue.Equals rather than ==, so that NaN compares appropriately.
            return other.type == type && other.stringValue == stringValue && other.numberValue.Equals(numberValue);
        }
    }
}
