// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT License.

// <auto-generated/>

#nullable disable

using System;
using System.ClientModel;
using System.ClientModel.Primitives;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;

namespace SampleTypeSpec
{
    /// <summary> The Notebooks sub-client. </summary>
    public partial class Notebooks
    {
        private readonly Uri _endpoint;
        private const string AuthorizationHeader = "my-api-key";
        /// <summary> The OAuth2 flows supported by the service. </summary>
        private static readonly Dictionary<string, object>[] _flows = new Dictionary<string, object>[] 
        {
            new Dictionary<string, object>
            {
                { GetTokenOptions.ScopesPropertyName, new string[] { "read" } },
                { GetTokenOptions.AuthorizationUrlPropertyName, "https://api.example.com/oauth2/authorize" },
                { GetTokenOptions.RefreshUrlPropertyName, "https://api.example.com/oauth2/refresh" }
            }
        };
        private readonly string _notebook;

        /// <summary> Initializes a new instance of Notebooks for mocking. </summary>
        protected Notebooks()
        {
        }

        /// <summary> Initializes a new instance of Notebooks. </summary>
        /// <param name="pipeline"> The HTTP pipeline for sending and receiving REST requests and responses. </param>
        /// <param name="endpoint"> Service endpoint. </param>
        /// <param name="notebook"></param>
        internal Notebooks(ClientPipeline pipeline, Uri endpoint, string notebook)
        {
            _endpoint = endpoint;
            Pipeline = pipeline;
            _notebook = notebook;
        }

        /// <summary> Initializes a new instance of Notebooks. </summary>
        /// <param name="endpoint"> Service endpoint. </param>
        /// <param name="notebook"></param>
        /// <param name="credential"> A credential used to authenticate to the service. </param>
        /// <exception cref="ArgumentNullException"> <paramref name="endpoint"/>, <paramref name="notebook"/> or <paramref name="credential"/> is null. </exception>
        /// <exception cref="ArgumentException"> <paramref name="notebook"/> is an empty string, and was expected to be non-empty. </exception>
        public Notebooks(Uri endpoint, string notebook, ApiKeyCredential credential) : this(endpoint, notebook, credential, new SampleTypeSpecClientOptions())
        {
        }

        /// <summary> Initializes a new instance of Notebooks. </summary>
        /// <param name="endpoint"> Service endpoint. </param>
        /// <param name="notebook"></param>
        /// <param name="tokenProvider"> A credential provider used to authenticate to the service. </param>
        /// <exception cref="ArgumentNullException"> <paramref name="endpoint"/>, <paramref name="notebook"/> or <paramref name="tokenProvider"/> is null. </exception>
        /// <exception cref="ArgumentException"> <paramref name="notebook"/> is an empty string, and was expected to be non-empty. </exception>
        public Notebooks(Uri endpoint, string notebook, AuthenticationTokenProvider tokenProvider) : this(endpoint, notebook, tokenProvider, new SampleTypeSpecClientOptions())
        {
        }

        /// <summary> Initializes a new instance of Notebooks. </summary>
        /// <param name="authenticationPolicy"> The authentication policy to use for pipeline creation. </param>
        /// <param name="endpoint"> Service endpoint. </param>
        /// <param name="notebook"></param>
        /// <param name="options"> The options for configuring the client. </param>
        internal Notebooks(AuthenticationPolicy authenticationPolicy, Uri endpoint, string notebook, SampleTypeSpecClientOptions options)
        {
            Argument.AssertNotNull(endpoint, nameof(endpoint));
            Argument.AssertNotNullOrEmpty(notebook, nameof(notebook));

            options ??= new SampleTypeSpecClientOptions();

            _endpoint = endpoint;
            _notebook = notebook;
            if (authenticationPolicy != null)
            {
                Pipeline = ClientPipeline.Create(options, Array.Empty<PipelinePolicy>(), new PipelinePolicy[] { new UserAgentPolicy(typeof(Notebooks).Assembly), authenticationPolicy }, Array.Empty<PipelinePolicy>());
            }
            else
            {
                Pipeline = ClientPipeline.Create(options, Array.Empty<PipelinePolicy>(), new PipelinePolicy[] { new UserAgentPolicy(typeof(Notebooks).Assembly) }, Array.Empty<PipelinePolicy>());
            }
        }

        /// <summary> Initializes a new instance of Notebooks. </summary>
        /// <param name="endpoint"> Service endpoint. </param>
        /// <param name="notebook"></param>
        /// <param name="credential"> A credential used to authenticate to the service. </param>
        /// <param name="options"> The options for configuring the client. </param>
        /// <exception cref="ArgumentNullException"> <paramref name="endpoint"/>, <paramref name="notebook"/> or <paramref name="credential"/> is null. </exception>
        /// <exception cref="ArgumentException"> <paramref name="notebook"/> is an empty string, and was expected to be non-empty. </exception>
        public Notebooks(Uri endpoint, string notebook, ApiKeyCredential credential, SampleTypeSpecClientOptions options) : this(ApiKeyAuthenticationPolicy.CreateHeaderApiKeyPolicy(credential, AuthorizationHeader), endpoint, notebook, options)
        {
        }

        /// <summary> Initializes a new instance of Notebooks. </summary>
        /// <param name="endpoint"> Service endpoint. </param>
        /// <param name="notebook"></param>
        /// <param name="tokenProvider"> A credential provider used to authenticate to the service. </param>
        /// <param name="options"> The options for configuring the client. </param>
        /// <exception cref="ArgumentNullException"> <paramref name="endpoint"/>, <paramref name="notebook"/> or <paramref name="tokenProvider"/> is null. </exception>
        /// <exception cref="ArgumentException"> <paramref name="notebook"/> is an empty string, and was expected to be non-empty. </exception>
        public Notebooks(Uri endpoint, string notebook, AuthenticationTokenProvider tokenProvider, SampleTypeSpecClientOptions options) : this(new BearerTokenPolicy(tokenProvider, _flows), endpoint, notebook, options)
        {
        }

        /// <summary> Initializes a new instance of Notebooks from a <see cref="NotebooksSettings"/>. </summary>
        /// <param name="settings"> The settings for Notebooks. </param>
        [Experimental("SCME0002")]
        public Notebooks(NotebooksSettings settings) : this(AuthenticationPolicy.Create(settings), settings?.SampleTypeSpecUrl, settings?.Notebook, settings?.Options)
        {
        }

        /// <summary> The HTTP pipeline for sending and receiving REST requests and responses. </summary>
        public ClientPipeline Pipeline { get; }

        /// <summary>
        /// [Protocol Method] Get a notebook by name
        /// <list type="bullet">
        /// <item>
        /// <description> This <see href="https://aka.ms/azsdk/net/protocol-methods">protocol method</see> allows explicit creation of the request and processing of the response for advanced scenarios. </description>
        /// </item>
        /// </list>
        /// </summary>
        /// <param name="options"> The request options, which can override default behaviors of the client pipeline on a per-call basis. </param>
        /// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
        /// <returns> The response returned from the service. </returns>
        public virtual ClientResult GetNotebook(RequestOptions options)
        {
            using PipelineMessage message = CreateGetNotebookRequest(options);
            return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options));
        }

        /// <summary>
        /// [Protocol Method] Get a notebook by name
        /// <list type="bullet">
        /// <item>
        /// <description> This <see href="https://aka.ms/azsdk/net/protocol-methods">protocol method</see> allows explicit creation of the request and processing of the response for advanced scenarios. </description>
        /// </item>
        /// </list>
        /// </summary>
        /// <param name="options"> The request options, which can override default behaviors of the client pipeline on a per-call basis. </param>
        /// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
        /// <returns> The response returned from the service. </returns>
        public virtual async Task<ClientResult> GetNotebookAsync(RequestOptions options)
        {
            using PipelineMessage message = CreateGetNotebookRequest(options);
            return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false));
        }

        /// <summary> Get a notebook by name. </summary>
        /// <param name="cancellationToken"> The cancellation token that can be used to cancel the operation. </param>
        /// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
        public virtual ClientResult<GetNotebookResponse> GetNotebook(CancellationToken cancellationToken = default)
        {
            ClientResult result = GetNotebook(cancellationToken.ToRequestOptions());
            return ClientResult.FromValue((GetNotebookResponse)result, result.GetRawResponse());
        }

        /// <summary> Get a notebook by name. </summary>
        /// <param name="cancellationToken"> The cancellation token that can be used to cancel the operation. </param>
        /// <exception cref="ClientResultException"> Service returned a non-success status code. </exception>
        public virtual async Task<ClientResult<GetNotebookResponse>> GetNotebookAsync(CancellationToken cancellationToken = default)
        {
            ClientResult result = await GetNotebookAsync(cancellationToken.ToRequestOptions()).ConfigureAwait(false);
            return ClientResult.FromValue((GetNotebookResponse)result, result.GetRawResponse());
        }
    }
}
