﻿using Lucene.Net.Diagnostics;
using Lucene.Net.Store;
using System;
using System.Runtime.CompilerServices;

namespace Lucene.Net.Util.Fst
{
    /*
     * 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.
     */

    /// <summary>
    /// An FST <see cref="Outputs{T}"/> implementation where each output
    /// is one or two non-negative long values.  If it's a
    /// <see cref="float"/> output, <see cref="Nullable{Int64}"/> is 
    /// returned; else, <see cref="TwoInt64s"/>.  Order
    /// is preserved in the <see cref="TwoInt64s"/> case, ie .first is the first
    /// input/output added to <see cref="Builder{T}"/>, and .second is the
    /// second.  You cannot store 0 output with this (that's
    /// reserved to mean "no output")!
    /// 
    /// <para>NOTE: the only way to create a TwoLongs output is to
    /// add the same input to the FST twice in a row.  This is
    /// how the FST maps a single input to two outputs (e.g. you
    /// cannot pass a <see cref="TwoInt64s"/> to <see cref="Builder{T}.Add(Int32sRef, T)"/>.  If you
    /// need more than two then use <see cref="ListOfOutputs{T}"/>, but if
    /// you only have at most 2 then this implementation will
    /// require fewer bytes as it steals one bit from each long
    /// value.
    /// 
    /// </para>
    /// <para>NOTE: the resulting FST is not guaranteed to be minimal!
    /// See <see cref="Builder{T}"/>.
    /// </para>
    /// <para>
    /// NOTE: This was UpToTwoPositiveIntOutputs in Lucene - the data type (int) was wrong there - it should have been long
    /// </para>
    /// @lucene.experimental
    /// </summary>
    public sealed class UpToTwoPositiveInt64Outputs : Outputs<object>
    {
        /// <summary>
        /// Holds two long outputs.
        /// <para/>
        /// NOTE: This was TwoLongs in Lucene
        /// </summary>
        public sealed class TwoInt64s
        {
            public long First => first;
            private readonly long first;

            public long Second => second;
            private readonly long second;

            public TwoInt64s(long first, long second)
            {
                this.first = first;
                this.second = second;
                if (Debugging.AssertsEnabled)
                {
                    Debugging.Assert(first >= 0);
                    Debugging.Assert(second >= 0);
                }
            }

            public override string ToString()
            {
                return "TwoLongs:" + first + "," + second;
            }

            public override bool Equals(object other)
            {
                if (other is TwoInt64s other2)
                {
                    return first == other2.first && second == other2.second;
                }
                else
                {
                    return false;
                }
            }

            public override int GetHashCode()
            {
                return (int)((first ^ ((long)((ulong)first >> 32))) ^ (second ^ (second >> 32)));
            }
        }

        private static readonly long? NO_OUTPUT = new long?(0);

        private readonly bool doShare;

        private static readonly UpToTwoPositiveInt64Outputs singletonShare = new UpToTwoPositiveInt64Outputs(true);
        private static readonly UpToTwoPositiveInt64Outputs singletonNoShare = new UpToTwoPositiveInt64Outputs(false);

        private UpToTwoPositiveInt64Outputs(bool doShare)
        {
            this.doShare = doShare;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static UpToTwoPositiveInt64Outputs GetSingleton(bool doShare)
        {
            return doShare ? singletonShare : singletonNoShare;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "This is a shipped public API")]
        public long? Get(long v)
        {
            return v == 0 ? NO_OUTPUT : v;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "This is a shipped public API")]
        public TwoInt64s Get(long first, long second)
        {
            return new TwoInt64s(first, second);
        }

        public override object Common(object output1, object output2)
        {
            if (Debugging.AssertsEnabled)
            {
                Debugging.Assert(Valid(output1, false));
                Debugging.Assert(Valid(output2, false));
            }
            long? output1_ = (long?)output1;
            long? output2_ = (long?)output2;
            if (output1_ == NO_OUTPUT || output2_ == NO_OUTPUT)
            {
                return NO_OUTPUT;
            }
            else if (doShare)
            {
                if (Debugging.AssertsEnabled)
                {
                    Debugging.Assert(output1_ > 0);
                    Debugging.Assert(output2_ > 0);
                }
                return Math.Min(output1_.GetValueOrDefault(), output2_.GetValueOrDefault());
            }
            else if (output1_.Equals(output2_))
            {
                return output1_;
            }
            else
            {
                return NO_OUTPUT;
            }
        }

        public override object Subtract(object output, object inc)
        {
            if (Debugging.AssertsEnabled)
            {
                Debugging.Assert(Valid(output, false));
                Debugging.Assert(Valid(inc, false));
            }
            long? output2 = (long?)output;
            long? inc2 = (long?)inc;
            if (Debugging.AssertsEnabled) Debugging.Assert(output2 >= inc2);

            if (inc2 == NO_OUTPUT)
            {
                return output2;
            }
            else if (output2.Equals(inc2))
            {
                return NO_OUTPUT;
            }
            else
            {
                return output2 - inc2;
            }
        }

        public override object Add(object prefix, object output)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(Valid(prefix, false));
            if (Debugging.AssertsEnabled) Debugging.Assert(Valid(output, true));
            long? prefix2 = (long?)prefix;
            if (output is long?)
            {
                long? output2 = (long?)output;
                if (prefix2 == NO_OUTPUT)
                {
                    return output2;
                }
                else if (output2 == NO_OUTPUT)
                {
                    return prefix2;
                }
                else
                {
                    return prefix2 + output2;
                }
            }
            else
            {
                TwoInt64s output3 = (TwoInt64s)output;
                long v = prefix2.Value;
                return new TwoInt64s(output3.First + v, output3.Second + v);
            }
        }

        public override void Write(object output, DataOutput @out)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(Valid(output, true));
            if (output is long?)
            {
                long? output2 = (long?)output;
                @out.WriteVInt64(output2.GetValueOrDefault() << 1);
            }
            else
            {
                TwoInt64s output3 = (TwoInt64s)output;
                @out.WriteVInt64((output3.First << 1) | 1);
                @out.WriteVInt64(output3.Second);
            }
        }

        public override object Read(DataInput @in)
        {
            long code = @in.ReadVInt64();
            if ((code & 1) == 0)
            {
                // single long
                long v = (long)((ulong)code >> 1);
                if (v == 0)
                {
                    return NO_OUTPUT;
                }
                else
                {
                    return v;
                }
            }
            else
            {
                // two longs
                long first = (long)((ulong)code >> 1);
                long second = @in.ReadVInt64();
                return new TwoInt64s(first, second);
            }
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private static bool Valid(long? o) // LUCENENET: CA1822: Mark members as static
        {
            Debugging.Assert(o != null);
            Debugging.Assert(o is long?);
            Debugging.Assert(o == NO_OUTPUT || o > 0);
            return true;
        }

        // Used only by assert
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private static bool Valid(object o, bool allowDouble) // LUCENENET: CA1822: Mark members as static
        {
            if (!allowDouble)
            {
                Debugging.Assert(o is long?);
                return Valid((long?)o);
            }
            else if (o is TwoInt64s)
            {
                return true;
            }
            else
            {
                return Valid((long?)o);
            }
        }

        public override object NoOutput => NO_OUTPUT;

        public override string OutputToString(object output)
        {
            return output.ToString();
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        public override object Merge(object first, object second)
        {
            if (Debugging.AssertsEnabled)
            {
                Debugging.Assert(Valid(first, false));
                Debugging.Assert(Valid(second, false));
            }
            return new TwoInt64s(((long?)first).GetValueOrDefault(), ((long?)second).GetValueOrDefault());
        }
    }
}