﻿#region License

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

#endregion

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Gremlin.Net.Process.Traversal;

namespace Gremlin.Net.Structure
{
    /// <summary>
    ///     A Path denotes a particular walk through a graph as defined by a <see cref="ITraversal" />.
    /// </summary>
    /// <remarks>
    ///     In abstraction, any Path implementation maintains two lists: a list of sets of labels and a list of objects.
    ///     The list of labels are the labels of the steps traversed. The list of objects are the objects traversed.
    /// </remarks>
    public class Path : IReadOnlyList<object?>, IEquatable<Path>
    {
        /// <summary>
        ///     Initializes a new instance of the <see cref="Path" /> class.
        /// </summary>
        /// <param name="labels">The labels associated with the path</param>
        /// <param name="objects">The objects in the <see cref="Path" />.</param>
        public Path(IList<ISet<string>> labels, IList<object?> objects)
        {
            Labels = labels ?? throw new ArgumentNullException(nameof(labels));
            Objects = objects ?? throw new ArgumentNullException(nameof(objects));
        }

        /// <summary>
        ///     Gets an ordered list of the labels associated with the <see cref="Path" />.
        /// </summary>
        public IList<ISet<string>> Labels { get; }

        /// <summary>
        ///     Gets an ordered list of the objects in the <see cref="Path" />.
        /// </summary>
        public IList<object?> Objects { get; }

        /// <summary>
        ///     Gets the object associated with the particular label of the path.
        /// </summary>
        /// <remarks>If the path has multiple labels of the type, then get a collection of those objects.</remarks>
        /// <param name="label">The label of the path</param>
        /// <returns>The object associated with the label of the path</returns>
        /// <exception cref="KeyNotFoundException">Thrown if the path does not contain the label.</exception>
        public object this[string label]
        {
            get
            {
                var objFound = TryGetValue(label, out var obj);
                if (!objFound)
                    throw new KeyNotFoundException($"The step with label {label} does not exist");
                return obj!;
            }
        }

        /// <inheritdoc />
        public bool Equals(Path? other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return ObjectsEqual(other.Objects) && LabelsEqual(other.Labels);
        }

        /// <summary>
        ///     Get the object associated with the specified index into the path.
        /// </summary>
        /// <param name="index">The index of the path</param>
        /// <returns>The object associated with the index of the path</returns>
        public dynamic? this[int index] => Objects[index];

        /// <summary>
        ///     Gets the number of steps in the path.
        /// </summary>
        public int Count => Objects.Count;

        /// <inheritdoc />
        public IEnumerator<object> GetEnumerator()
        {
            return ((IReadOnlyList<object>) Objects).GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IReadOnlyList<object>) Objects).GetEnumerator();
        }

        /// <inheritdoc />
        public override string ToString()
        {
            return $"path[{string.Join(", ", Objects)}]";
        }

        /// <summary>
        ///     Returns true if the path has the specified label, else return false.
        /// </summary>
        /// <param name="key">The label to search for.</param>
        /// <returns>True if the label exists in the path.</returns>
        public bool ContainsKey(string key)
        {
            return Labels.Any(objLabels => objLabels.Contains(key));
        }

        /// <summary>
        ///     Tries to get the object associated with the particular label of the path.
        /// </summary>
        /// <remarks>If the path has multiple labels of the type, then get a collection of those objects.</remarks>
        /// <param name="label">The label of the path.</param>
        /// <param name="value">The object associated with the label of the path.</param>
        /// <returns>True, if an object was found for the label.</returns>
        public bool TryGetValue(string label, [NotNullWhen(true)] out object? value)
        {
            value = null;
            for (var i = 0; i < Labels.Count; i++)
            {
                if (!Labels[i].Contains(label)) continue;
                if (value == null)
                    value = Objects[i];
                else if (value.GetType() == typeof(List<object?>))
                    ((List<object?>) value).Add(Objects[i]);
                else
                    value = new List<object?> {value, Objects[i]};
            }
            return value != null;
        }

        private bool ObjectsEqual(ICollection<object?> otherObjects)
        {
            return Objects.SequenceEqual(otherObjects);
        }

        private bool LabelsEqual(ICollection<ISet<string>> otherLabels)
        {
            if (Labels.Count != otherLabels.Count)
                return false;
            using var enumOther = otherLabels.GetEnumerator();
            using var enumThis = Labels.GetEnumerator();
            while (enumOther.MoveNext() && enumThis.MoveNext())
            {
                if (!enumOther.Current.SequenceEqual(enumThis.Current))
                {
                    return false;
                }
            }

            return true;
        }

        /// <inheritdoc />
        public override bool Equals(object? obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != GetType()) return false;
            return Equals((Path) obj);
        }

        /// <inheritdoc />
        public override int GetHashCode()
        {
            unchecked
            {
                var hashCode = 19;
                hashCode = Labels
                    .Aggregate(hashCode,
                        (current1, objLabels) => objLabels.Aggregate(current1,
                            (current, label) => current * 31 + label.GetHashCode()));
                hashCode = Objects.Aggregate(hashCode,
                    (current, obj) => current * 31 + (obj == null ? 0 : obj.GetHashCode()));
                return hashCode;
            }
        }
    }
}