// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable disable

using System;
using System.Globalization;
using Microsoft.Extensions.Internal;

namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration;

public readonly struct LinePragma : IEquatable<LinePragma>
{
    public LinePragma(int startLineIndex, int lineCount, string filePath)
        : this(startLineIndex: startLineIndex, lineCount: lineCount, filePath: filePath, startCharacterIndex: null, endCharacterIndex: null, characterOffset: null)
    {
    }

    public LinePragma(int startLineIndex, int lineCount, string filePath, int? startCharacterIndex, int? endCharacterIndex, int? characterOffset)
    {
        if (startLineIndex < 0)
        {
            throw new ArgumentOutOfRangeException(nameof(startLineIndex));
        }

        if (lineCount < 0)
        {
            throw new ArgumentOutOfRangeException(nameof(lineCount));
        }

        StartLineIndex = startLineIndex;
        LineCount = lineCount;
        FilePath = filePath;
        StartCharacterIndex = startCharacterIndex;
        EndCharacterIndex = endCharacterIndex;
        CharacterOffset = characterOffset;
    }

    public int StartLineIndex { get; }

    public int EndLineIndex => StartLineIndex + LineCount;

    public int LineCount { get; }

    public int? StartCharacterIndex { get; }

    public int? EndCharacterIndex { get; }

    public int? CharacterOffset { get; }

    public string FilePath { get; }

    public override bool Equals(object obj)
    {
        return obj is LinePragma other ? Equals(other) : false;
    }

    public bool Equals(LinePragma other)
    {
        return StartLineIndex == other.StartLineIndex &&
            LineCount == other.LineCount &&
            string.Equals(FilePath, other.FilePath, StringComparison.Ordinal);
    }

    public override int GetHashCode()
    {
        var hash = HashCodeCombiner.Start();
        hash.Add(StartLineIndex);
        hash.Add(LineCount);
        hash.Add(FilePath);
        return hash;
    }

    public override string ToString()
    {
        return string.Format(CultureInfo.CurrentCulture, "Line index {0}, Count {1} - {2}", StartLineIndex, LineCount, FilePath);
    }
}
