// <copyright file="Command.cs" company="Selenium Committers">
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC 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.
// </copyright>

using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
using OpenQA.Selenium.Internal;

namespace OpenQA.Selenium;

/// <summary>
/// Provides a way to send commands to the remote server
/// </summary>
public class Command
{
    private readonly static JsonSerializerOptions s_jsonSerializerOptions = new()
    {
        TypeInfoResolverChain =
        {
            CommandJsonSerializerContext.Default,
            new DefaultJsonTypeInfoResolver()
        },
        Converters = { new ResponseValueJsonConverter() }
    };

    /// <summary>
    /// Initializes a new instance of the <see cref="Command"/> class using a command name and a JSON-encoded string for the parameters.
    /// </summary>
    /// <param name="name">Name of the command</param>
    /// <param name="jsonParameters">Parameters for the command as a JSON-encoded string.</param>
    public Command(string name, string jsonParameters)
        : this(null, name, ConvertParametersFromJson(jsonParameters))
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="Command"/> class for a Session
    /// </summary>
    /// <param name="sessionId">Session ID the driver is using</param>
    /// <param name="name">Name of the command</param>
    /// <param name="parameters">Parameters for that command</param>
    /// <exception cref="ArgumentNullException">If <paramref name="name"/> is <see langword="null"/>.</exception>
    public Command(SessionId? sessionId, string name, Dictionary<string, object?>? parameters)
    {
        ArgumentNullException.ThrowIfNull(name);
        this.SessionId = sessionId;
        this.Parameters = parameters ?? new Dictionary<string, object?>();
        this.Name = name;
    }

    /// <summary>
    /// Gets the SessionID of the command
    /// </summary>
    [JsonPropertyName("sessionId")]
    public SessionId? SessionId { get; }

    /// <summary>
    /// Gets the command name
    /// </summary>
    [JsonPropertyName("name")]
    public string Name { get; }

    /// <summary>
    /// Gets the parameters of the command
    /// </summary>
    [JsonPropertyName("parameters")]
    public Dictionary<string, object?> Parameters { get; }

    /// <summary>
    /// Gets the parameters of the command as a JSON-encoded string.
    /// </summary>
    public string ParametersAsJsonString
    {
        get
        {
            if (this.Parameters != null && this.Parameters.Count > 0)
            {
                return JsonSerializer.Serialize(this.Parameters, s_jsonSerializerOptions);
            }
            else
            {
                return "{}";
            }
        }
    }

    /// <summary>
    /// Returns a string of the Command object
    /// </summary>
    /// <returns>A string representation of the Command Object</returns>
    public override string ToString()
    {
        return string.Concat("[", this.SessionId, "]: ", this.Name, " ", this.ParametersAsJsonString);
    }

    /// <summary>
    /// Gets the command parameters as a <see cref="Dictionary{K, V}"/>, with a string key, and an object value.
    /// </summary>
    /// <param name="value">The JSON-encoded string representing the command parameters.</param>
    /// <returns>A <see cref="Dictionary{K, V}"/> with a string keys, and an object value. </returns>
    /// <exception cref="JsonException">If <paramref name="value"/> is not a JSON object.</exception>
    /// <exception cref="ArgumentNullException">If <paramref name="value"/> is <see langword="null"/>.</exception>
    private static Dictionary<string, object?>? ConvertParametersFromJson(string value)
    {
        Dictionary<string, object?>? parameters = JsonSerializer.Deserialize<Dictionary<string, object?>>(value, CommandJsonSerializerContext.Default.DictionaryStringObject!);
        return parameters;
    }
}

// Built-in types
[JsonSerializable(typeof(bool))]
[JsonSerializable(typeof(byte))]
[JsonSerializable(typeof(sbyte))]
[JsonSerializable(typeof(char))]
[JsonSerializable(typeof(decimal))]
[JsonSerializable(typeof(double))]
[JsonSerializable(typeof(float))]
[JsonSerializable(typeof(int))]
[JsonSerializable(typeof(uint))]
[JsonSerializable(typeof(nint))]
[JsonSerializable(typeof(nuint))]
[JsonSerializable(typeof(long))]
[JsonSerializable(typeof(ulong))]
[JsonSerializable(typeof(short))]
[JsonSerializable(typeof(ushort))]
[JsonSerializable(typeof(string))]

// Selenium WebDriver types
[JsonSerializable(typeof(char[]))]
[JsonSerializable(typeof(byte[]))]
[JsonSerializable(typeof(Chromium.ChromiumNetworkConditions))]
[JsonSerializable(typeof(Cookie))]
[JsonSerializable(typeof(ReturnedCookie))]
[JsonSerializable(typeof(Proxy))]

// Selenium Dictionaries, primarily used in Capabilities
[JsonSerializable(typeof(Dictionary<string, object>))]
[JsonSerializable(typeof(Dictionary<string, bool>))]
[JsonSerializable(typeof(Dictionary<string, byte>))]
[JsonSerializable(typeof(Dictionary<string, sbyte>))]
[JsonSerializable(typeof(Dictionary<string, char>))]
[JsonSerializable(typeof(Dictionary<string, decimal>))]
[JsonSerializable(typeof(Dictionary<string, double>))]
[JsonSerializable(typeof(Dictionary<string, float>))]
[JsonSerializable(typeof(Dictionary<string, int>))]
[JsonSerializable(typeof(Dictionary<string, uint>))]
[JsonSerializable(typeof(Dictionary<string, nint>))]
[JsonSerializable(typeof(Dictionary<string, nuint>))]
[JsonSerializable(typeof(Dictionary<string, long>))]
[JsonSerializable(typeof(Dictionary<string, ulong>))]
[JsonSerializable(typeof(Dictionary<string, short>))]
[JsonSerializable(typeof(Dictionary<string, ushort>))]
[JsonSerializable(typeof(Dictionary<string, string>))]
#pragma warning disable CS3016 // Arrays as attribute arguments is not CLS-compliant
// This is not part of the public API, so we can ignore this warning
[JsonSourceGenerationOptions(Converters = [typeof(ResponseValueJsonConverter)])]
#pragma warning restore CS3016 // Arrays as attribute arguments is not CLS-compliant
internal partial class CommandJsonSerializerContext : JsonSerializerContext;
