/*
* 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.
*/

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Apache.Arrow.Adbc.Extensions;
using Apache.Arrow.Adbc.Telemetry.Traces.Listeners;
using Apache.Arrow.Adbc.Telemetry.Traces.Listeners.FileListener;
using Apache.Arrow.Adbc.Tracing;
using Apache.Arrow.Ipc;
using Apache.Arrow.Types;
using Google.Api.Gax;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Bigquery.v2.Data;
using Google.Cloud.BigQuery.V2;

namespace Apache.Arrow.Adbc.Drivers.BigQuery
{
    /// <summary>
    /// BigQuery-specific implementation of <see cref="AdbcConnection"/>
    /// </summary>
    public class BigQueryConnection : TracingConnection, ITokenProtectedResource
    {
        readonly Dictionary<string, string> properties;
        readonly HttpClient httpClient;
        bool includePublicProjectIds = false;
        const string infoDriverName = "ADBC BigQuery Driver";
        const string infoVendorName = "BigQuery";
        // Note: this needs to be set before the constructor runs
        private readonly string _traceInstanceId = Guid.NewGuid().ToString("N");
        private readonly FileActivityListener? _fileActivityListener;

        private readonly string infoDriverArrowVersion = BigQueryUtils.GetAssemblyVersion(typeof(IArrowArray));

        readonly AdbcInfoCode[] infoSupportedCodes = new[] {
            AdbcInfoCode.DriverName,
            AdbcInfoCode.DriverVersion,
            AdbcInfoCode.DriverArrowVersion,
            AdbcInfoCode.VendorName
        };

        public BigQueryConnection(IReadOnlyDictionary<string, string> properties) : base(properties)
        {
            if (properties == null)
            {
                this.properties = new Dictionary<string, string>();
            }
            else
            {
                this.properties = properties.ToDictionary(k => k.Key, v => v.Value);
            }

            TryInitTracerProvider(out _fileActivityListener);

            this.httpClient = new HttpClient();

            if (this.properties.TryGetValue(BigQueryParameters.LargeDecimalsAsString, out string? sLargeDecimalsAsString) &&
                bool.TryParse(sLargeDecimalsAsString, out bool largeDecimalsAsString))
            {
                this.properties[BigQueryParameters.LargeDecimalsAsString] = largeDecimalsAsString.ToString();
            }
            else
            {
                this.properties[BigQueryParameters.LargeDecimalsAsString] = BigQueryConstants.TreatLargeDecimalAsString;
            }

            if (this.properties.TryGetValue(BigQueryParameters.MaximumRetryAttempts, out string? sRetryAttempts) &&
                int.TryParse(sRetryAttempts, out int retries) &&
                retries >= 0)
            {
                MaxRetryAttempts = retries;
            }

            if (this.properties.TryGetValue(BigQueryParameters.RetryDelayMs, out string? sRetryDelay) &&
                int.TryParse(sRetryDelay, out int delay) &&
                delay >= 0)
            {
                RetryDelayMs = delay;
            }

            if (this.properties.TryGetValue(BigQueryParameters.DefaultClientLocation, out string? location) &&
                !string.IsNullOrEmpty(location) &&
                BigQueryConstants.ValidLocations.Any(l => l.Equals(location, StringComparison.OrdinalIgnoreCase)))
            {
                DefaultClientLocation = location;
            }
        }

        private bool TryInitTracerProvider(out FileActivityListener? fileActivityListener)
        {
            properties.TryGetValue(ListenersOptions.Exporter, out string? exporterOption);
            // This listener will only listen for activity from this specific connection instance.
            bool shouldListenTo(ActivitySource source) => source.Tags?.Any(t => ReferenceEquals(t.Key, _traceInstanceId)) == true;
            return FileActivityListener.TryActivateFileListener(AssemblyName, exporterOption, out fileActivityListener, shouldListenTo: shouldListenTo);
        }

        public override IEnumerable<KeyValuePair<string, object?>>? GetActivitySourceTags(IReadOnlyDictionary<string, string> properties)
        {
            IEnumerable<KeyValuePair<string, object?>>? tags = base.GetActivitySourceTags(properties);
            tags ??= [];
            tags = tags.Concat([new(_traceInstanceId, null)]);
            return tags;
        }

        /// <summary>
        /// Conditional used to determines if it is safe to trace
        /// </summary>
        /// <remarks>
        /// It is safe to write to some output types (ie, files) but not others (ie, a shared resource).
        /// </remarks>
        /// <returns></returns>
        internal bool IsSafeToTrace => _fileActivityListener != null;

        /// <summary>
        /// The function to call when updating the token.
        /// </summary>
        public Func<Task>? UpdateToken { get; set; }

        internal string DriverName => infoDriverName;

        internal BigQueryClient? Client { get; private set; }

        internal GoogleCredential? Credential { get; private set; }

        internal int MaxRetryAttempts { get; private set; } = 5;

        internal int RetryDelayMs { get; private set; } = 200;

        // if this value is null, the BigQuery API chooses the location (typically the `US` multi-region)
        internal string? DefaultClientLocation { get; private set; }

        public override string AssemblyVersion => BigQueryUtils.BigQueryAssemblyVersion;

        public override string AssemblyName => BigQueryUtils.BigQueryAssemblyName;

        /// <summary>
        /// Initializes the internal BigQuery connection
        /// </summary>
        /// <param name="projectId">A project ID that has been specified by the caller, not a user.</param>
        /// <exception cref="ArgumentException"></exception>
        internal BigQueryClient Open(string? projectId = null)
        {
            return this.TraceActivity(activity =>
            {
                string? billingProjectId = null;
                TimeSpan? clientTimeout = null;

                if (string.IsNullOrEmpty(projectId))
                {
                    // if the caller doesn't specify a projectId, use the default
                    if (!this.properties.TryGetValue(BigQueryParameters.ProjectId, out projectId))
                    {
                        projectId = BigQueryConstants.DetectProjectId;
                    }
                    else
                    {
                        activity?.AddBigQueryParameterTag(BigQueryParameters.ProjectId, projectId);
                    }

                    // in some situations, the publicProjectId gets passed and causes an error when we try to create a query job:
                    //     Google.GoogleApiException : The service bigquery has thrown an exception. HttpStatusCode is Forbidden.
                    //     Access Denied: Project bigquery-public-data: User does not have bigquery.jobs.create permission in
                    //     project bigquery-public-data.
                    // so if that is the case, treat it as if we need to detect the projectId
                    if (projectId.Equals(BigQueryConstants.PublicProjectId, StringComparison.OrdinalIgnoreCase))
                    {
                        projectId = BigQueryConstants.DetectProjectId;
                        activity?.AddBigQueryTag("change_public_projectId_to_detect_project_id", projectId);
                    }
                }

                // the billing project can be null if it's not specified
                if (this.properties.TryGetValue(BigQueryParameters.BillingProjectId, out billingProjectId))
                {
                    activity?.AddBigQueryParameterTag((BigQueryParameters.BillingProjectId), billingProjectId);
                }

                if (this.properties.TryGetValue(BigQueryParameters.IncludePublicProjectId, out string? result))
                {
                    if (!string.IsNullOrEmpty(result))
                    {
                        this.includePublicProjectIds = Convert.ToBoolean(result);
                        activity?.AddBigQueryParameterTag(BigQueryParameters.IncludePublicProjectId, this.includePublicProjectIds);
                    }
                }

                if (this.properties.TryGetValue(BigQueryParameters.ClientTimeout, out string? timeoutSeconds) &&
                    int.TryParse(timeoutSeconds, out int seconds))
                {
                    clientTimeout = TimeSpan.FromSeconds(seconds);
                    activity?.AddBigQueryParameterTag(BigQueryParameters.ClientTimeout, seconds);
                }

                SetCredential();

                BigQueryClientBuilder bigQueryClientBuilder = new BigQueryClientBuilder()
                {
                    ProjectId = projectId,
                    QuotaProject = billingProjectId,
                    GoogleCredential = Credential
                };

                if (!string.IsNullOrEmpty(DefaultClientLocation))
                {
                    // If the user selects a public dataset (from a multi-region) but sets this
                    // value to a specific location like us-east4, then there is an error produced
                    // that the caller doesn't have permission to call to the public dataset.
                    // Example:
                    //    Access Denied: Table bigquery-public-data:blockchain_analytics_ethereum_mainnet_us.accounts:
                    //    User does not have permission to query table bigquery-public-data:blockchain_analytics_ethereum_mainnet_us.accounts,
                    //    or perhaps it does not exist.'

                    bigQueryClientBuilder.DefaultLocation = DefaultClientLocation;
                    activity?.AddBigQueryParameterTag(BigQueryParameters.DefaultClientLocation, DefaultClientLocation);
                }
                else
                {
                    activity?.AddBigQueryTag("client.default_location", null);
                }

                BigQueryClient client = bigQueryClientBuilder.Build();

                if (clientTimeout.HasValue)
                {
                    client.Service.HttpClient.Timeout = clientTimeout.Value;
                }

                Client = client;
                return client;
            });
        }

        internal void SetCredential()
        {
            this.TraceActivity(activity =>
            {
                string? clientId = null;
                string? clientSecret = null;
                string? refreshToken = null;
                string? accessToken = null;
                string? audienceUri = null;
                string? authenticationType = null;

                string tokenEndpoint = BigQueryConstants.TokenEndpoint;

                if (!this.properties.TryGetValue(BigQueryParameters.AuthenticationType, out authenticationType))
                {
                    throw new ArgumentException($"The {BigQueryParameters.AuthenticationType} parameter is not present");
                }

                if (this.properties.TryGetValue(BigQueryParameters.AuthenticationType, out string? newAuthenticationType))
                {
                    if (!string.IsNullOrEmpty(newAuthenticationType))
                        authenticationType = newAuthenticationType;

                    if (!authenticationType.Equals(BigQueryConstants.UserAuthenticationType, StringComparison.OrdinalIgnoreCase) &&
                        !authenticationType.Equals(BigQueryConstants.ServiceAccountAuthenticationType, StringComparison.OrdinalIgnoreCase) &&
                        !authenticationType.Equals(BigQueryConstants.EntraIdAuthenticationType, StringComparison.OrdinalIgnoreCase))
                    {
                        throw new ArgumentException($"The {BigQueryParameters.AuthenticationType} parameter can only be `{BigQueryConstants.UserAuthenticationType}`, `{BigQueryConstants.ServiceAccountAuthenticationType}` or `{BigQueryConstants.EntraIdAuthenticationType}`");
                    }
                    else
                    {
                        activity?.AddBigQueryParameterTag((BigQueryParameters.AuthenticationType), authenticationType);
                    }
                }

                if (!string.IsNullOrEmpty(authenticationType) && authenticationType.Equals(BigQueryConstants.UserAuthenticationType, StringComparison.OrdinalIgnoreCase))
                {
                    if (!this.properties.TryGetValue(BigQueryParameters.ClientId, out clientId))
                        throw new ArgumentException($"The {BigQueryParameters.ClientId} parameter is not present");

                    if (!this.properties.TryGetValue(BigQueryParameters.ClientSecret, out clientSecret))
                        throw new ArgumentException($"The {BigQueryParameters.ClientSecret} parameter is not present");

                    if (!this.properties.TryGetValue(BigQueryParameters.RefreshToken, out refreshToken))
                        throw new ArgumentException($"The {BigQueryParameters.RefreshToken} parameter is not present");

                    Credential = ApplyScopes(GoogleCredential.FromAccessToken(GetAccessToken(clientId, clientSecret, refreshToken, tokenEndpoint)));
                }
                else if (!string.IsNullOrEmpty(authenticationType) && authenticationType.Equals(BigQueryConstants.EntraIdAuthenticationType, StringComparison.OrdinalIgnoreCase))
                {
                    if (!this.properties.TryGetValue(BigQueryParameters.AccessToken, out accessToken))
                        throw new ArgumentException($"The {BigQueryParameters.AccessToken} parameter is not present");

                    if (!this.properties.TryGetValue(BigQueryParameters.AudienceUri, out audienceUri))
                        throw new ArgumentException($"The {BigQueryParameters.AudienceUri} parameter is not present");

                    Credential = ApplyScopes(GoogleCredential.FromAccessToken(TradeEntraIdTokenForBigQueryToken(audienceUri, accessToken)));
                }
                else if (!string.IsNullOrEmpty(authenticationType) && authenticationType.Equals(BigQueryConstants.ServiceAccountAuthenticationType, StringComparison.OrdinalIgnoreCase))
                {
                    string? json = string.Empty;

                    if (!this.properties.TryGetValue(BigQueryParameters.JsonCredential, out json))
                        throw new ArgumentException($"The {BigQueryParameters.JsonCredential} parameter is not present");

                    Credential = ApplyScopes(GoogleCredential.FromJson(json));
                }
                else
                {
                    throw new ArgumentException($"{authenticationType} is not a valid authenticationType");
                }
            });
        }

        public override void SetOption(string key, string value)
        {
            this.TraceActivity(activity =>
            {
                activity?.AddTag(key + ".set", value);

                this.properties[key] = value;

                if (key.Equals(BigQueryParameters.AccessToken))
                {
                    UpdateClientToken();
                }
            });
        }

        /// <summary>
        /// Apply any additional scopes to the credential.
        /// </summary>
        /// <param name="credential"><see cref="GoogleCredential"/></param>
        /// <returns></returns>
        private GoogleCredential ApplyScopes(GoogleCredential credential)
        {
            if (credential == null) throw new ArgumentNullException(nameof(credential));

            if (this.properties.TryGetValue(BigQueryParameters.Scopes, out string? scopes))
            {
                if (!string.IsNullOrEmpty(scopes))
                {
                    IEnumerable<string> parsedScopes = scopes.Split(',').Where(x => x.Length > 0);

                    return credential.CreateScoped(parsedScopes);
                }
            }

            return credential;
        }

        public override IArrowArrayStream GetInfo(IReadOnlyList<AdbcInfoCode> codes)
        {
            return this.TraceActivity(activity =>
            {
                const int strValTypeID = 0;

                UnionType infoUnionType = new UnionType(
                    new Field[]
                    {
                    new Field("string_value", StringType.Default, true),
                    new Field("bool_value", BooleanType.Default, true),
                    new Field("int64_value", Int64Type.Default, true),
                    new Field("int32_bitmask", Int32Type.Default, true),
                    new Field(
                        "string_list",
                        new ListType(
                            new Field("item", StringType.Default, true)
                        ),
                        false
                    ),
                    new Field(
                        "int32_to_int32_list_map",
                        new ListType(
                            new Field("entries", new StructType(
                                new Field[]
                                {
                                    new Field("key", Int32Type.Default, false),
                                    new Field("value", Int32Type.Default, true),
                                }
                                ), false)
                        ),
                        true
                    )
                    },
                    new int[] { 0, 1, 2, 3, 4, 5 }.ToArray(),
                    UnionMode.Dense);

                if (codes.Count == 0)
                {
                    codes = infoSupportedCodes;
                }

                UInt32Array.Builder infoNameBuilder = new UInt32Array.Builder();
                ArrowBuffer.Builder<byte> typeBuilder = new ArrowBuffer.Builder<byte>();
                ArrowBuffer.Builder<int> offsetBuilder = new ArrowBuffer.Builder<int>();
                StringArray.Builder stringInfoBuilder = new StringArray.Builder();
                int nullCount = 0;
                int arrayLength = codes.Count;

                foreach (AdbcInfoCode code in codes)
                {
                    string tagKey = SemanticConventions.Db.Operation.Parameter(code.ToString().ToLowerInvariant());
                    string? tagValue = null;
                    switch (code)
                    {
                        case AdbcInfoCode.DriverName:
                            infoNameBuilder.Append((UInt32)code);
                            typeBuilder.Append(strValTypeID);
                            offsetBuilder.Append(stringInfoBuilder.Length);
                            stringInfoBuilder.Append(infoDriverName);
                            tagValue = infoDriverName;
                            break;
                        case AdbcInfoCode.DriverVersion:
                            infoNameBuilder.Append((UInt32)code);
                            typeBuilder.Append(strValTypeID);
                            offsetBuilder.Append(stringInfoBuilder.Length);
                            stringInfoBuilder.Append(BigQueryUtils.BigQueryAssemblyVersion);
                            tagValue = BigQueryUtils.BigQueryAssemblyVersion;
                            break;
                        case AdbcInfoCode.DriverArrowVersion:
                            infoNameBuilder.Append((UInt32)code);
                            typeBuilder.Append(strValTypeID);
                            offsetBuilder.Append(stringInfoBuilder.Length);
                            stringInfoBuilder.Append(infoDriverArrowVersion);
                            tagValue = infoDriverArrowVersion;
                            break;
                        case AdbcInfoCode.VendorName:
                            infoNameBuilder.Append((UInt32)code);
                            typeBuilder.Append(strValTypeID);
                            offsetBuilder.Append(stringInfoBuilder.Length);
                            stringInfoBuilder.Append(infoVendorName);
                            tagValue = infoVendorName;
                            break;
                        default:
                            infoNameBuilder.Append((UInt32)code);
                            typeBuilder.Append(strValTypeID);
                            offsetBuilder.Append(stringInfoBuilder.Length);
                            stringInfoBuilder.AppendNull();
                            nullCount++;
                            break;
                    }
                    activity?.AddTag(tagKey, tagValue);
                }

                StructType entryType = new StructType(
                    new Field[] {
                    new Field("key", Int32Type.Default, false),
                    new Field("value", Int32Type.Default, true)});

                StructArray entriesDataArray = new StructArray(entryType, 0,
                    new[] { new Int32Array.Builder().Build(), new Int32Array.Builder().Build() },
                    new ArrowBuffer.BitmapBuilder().Build());

                IArrowArray[] childrenArrays = new IArrowArray[]
                {
                stringInfoBuilder.Build(),
                new BooleanArray.Builder().Build(),
                new Int64Array.Builder().Build(),
                new Int32Array.Builder().Build(),
                new ListArray.Builder(StringType.Default).Build(),
                new List<IArrowArray?>(){ entriesDataArray }.BuildListArrayForType(entryType)
                };

                DenseUnionArray infoValue = new DenseUnionArray(infoUnionType, arrayLength, childrenArrays, typeBuilder.Build(), offsetBuilder.Build(), nullCount);

                IArrowArray[] dataArrays = new IArrowArray[]
                {
                infoNameBuilder.Build(),
                infoValue
                };
                StandardSchemas.GetInfoSchema.Validate(dataArrays);

                return new BigQueryInfoArrowStream(StandardSchemas.GetInfoSchema, dataArrays);
            });
        }

        public override IArrowArrayStream GetObjects(
            GetObjectsDepth depth,
            string? catalogPattern,
            string? dbSchemaPattern,
            string? tableNamePattern,
            IReadOnlyList<string>? tableTypes,
            string? columnNamePattern)
        {
            return this.TraceActivity(activity =>
            {
                IArrowArray[] dataArrays = GetCatalogs(depth, catalogPattern, dbSchemaPattern,
                    tableNamePattern, tableTypes, columnNamePattern);

                return new BigQueryInfoArrowStream(StandardSchemas.GetObjectsSchema, dataArrays);
            });
        }

        /// <summary>
        /// Renews the internal BigQueryClient with updated credentials.
        /// </summary>
        internal void UpdateClientToken()
        {
            // there isn't a way to set the credentials, just need to open a new client
            Client = Open();
        }

        /// <summary>
        /// Determines if the token needs to be updated.
        /// </summary>
        public bool TokenRequiresUpdate(Exception ex) => BigQueryUtils.TokenRequiresUpdate(ex);

        private async Task<T> ExecuteWithRetriesAsync<T>(Func<Task<T>> action, Activity? activity) => await RetryManager.ExecuteWithRetriesAsync<T>(this, action, activity, MaxRetryAttempts, RetryDelayMs);

        /// <summary>
        /// Executes the query using the BigQueryClient.
        /// </summary>
        /// <param name="sql">The query to execute.</param>
        /// <param name="parameters">Parameters to include.</param>
        /// <param name="queryOptions">Additional query options.</param>
        /// <param name="resultsOptions">Additional result options.</param>
        /// <returns></returns>
        /// <remarks>
        /// Can later add logging or metrics around query calls.
        /// </remarks>
        private BigQueryResults? ExecuteQuery(string sql, IEnumerable<BigQueryParameter>? parameters, QueryOptions? queryOptions = null, GetQueryResultsOptions? resultsOptions = null)
        {
            if (Client == null) { Client = Open(); }

            return this.TraceActivity(activity =>
            {
                activity?.AddConditionalTag(SemanticConventions.Db.Query.Text, sql, IsSafeToTrace);

                Func<Task<BigQueryResults?>> func = () => Client.ExecuteQueryAsync(sql, parameters ?? Enumerable.Empty<BigQueryParameter>(), queryOptions, resultsOptions);
                BigQueryResults? result = ExecuteWithRetriesAsync<BigQueryResults?>(func, activity).GetAwaiter().GetResult();

                return result;
            });
        }

        private IArrowArray[] GetCatalogs(
            GetObjectsDepth depth,
            string? catalogPattern,
            string? dbSchemaPattern,
            string? tableNamePattern,
            IReadOnlyList<string>? tableTypes,
            string? columnNamePattern)
        {
            return this.TraceActivity(activity =>
            {
                StringArray.Builder catalogNameBuilder = new StringArray.Builder();
                List<IArrowArray?> catalogDbSchemasValues = new List<IArrowArray?>();
                string catalogRegexp = PatternToRegEx(catalogPattern);
                PagedEnumerable<ProjectList, CloudProject>? catalogs;
                List<string> projectIds = new List<string>();

                Func<Task<PagedEnumerable<ProjectList, CloudProject>?>> func = () => Task.Run(() =>
                {
                    // stick with this call because PagedAsyncEnumerable has different behaviors for selecting items
                    return Client?.ListProjects();
                });

                catalogs = ExecuteWithRetriesAsync<PagedEnumerable<ProjectList, CloudProject>?>(func, activity).GetAwaiter().GetResult();

                if (catalogs != null)
                {
                    projectIds = catalogs.Select(x => x.ProjectId).ToList();
                }

                if (this.includePublicProjectIds && !projectIds.Contains(BigQueryConstants.PublicProjectId))
                    projectIds.Add(BigQueryConstants.PublicProjectId);

                projectIds.Sort();

                foreach (string projectId in projectIds)
                {
                    if (Regex.IsMatch(projectId, catalogRegexp, RegexOptions.IgnoreCase))
                    {
                        catalogNameBuilder.Append(projectId);

                        if (depth == GetObjectsDepth.Catalogs)
                        {
                            catalogDbSchemasValues.Add(null);
                        }
                        else
                        {
                            catalogDbSchemasValues.Add(GetDbSchemas(
                                depth, projectId, dbSchemaPattern,
                                tableNamePattern, tableTypes, columnNamePattern));
                        }
                    }
                }

                IArrowArray[] dataArrays = new IArrowArray[]
                {
                catalogNameBuilder.Build(),
                catalogDbSchemasValues.BuildListArrayForType(new StructType(StandardSchemas.DbSchemaSchema)),
                };

                StandardSchemas.GetObjectsSchema.Validate(dataArrays);

                return dataArrays;
            });
        }

        private StructArray GetDbSchemas(
            GetObjectsDepth depth,
            string catalog,
            string? dbSchemaPattern,
            string? tableNamePattern,
            IReadOnlyList<string>? tableTypes,
            string? columnNamePattern)
        {
            return this.TraceActivity(activity =>
            {
                StringArray.Builder dbSchemaNameBuilder = new StringArray.Builder();
                List<IArrowArray?> dbSchemaTablesValues = new List<IArrowArray?>();
                ArrowBuffer.BitmapBuilder nullBitmapBuffer = new ArrowBuffer.BitmapBuilder();
                int length = 0;

                string dbSchemaRegexp = PatternToRegEx(dbSchemaPattern);

                Func<Task<PagedEnumerable<DatasetList, BigQueryDataset>?>> func = () => Task.Run(() =>
                {
                    // stick with this call because PagedAsyncEnumerable has different behaviors for selecting items
                    return Client?.ListDatasets(catalog);
                });

                PagedEnumerable<DatasetList, BigQueryDataset>? schemas = ExecuteWithRetriesAsync<PagedEnumerable<DatasetList, BigQueryDataset>?>(func, activity).GetAwaiter().GetResult();

                if (schemas != null)
                {
                    foreach (BigQueryDataset schema in schemas)
                    {
                        if (Regex.IsMatch(schema.Reference.DatasetId, dbSchemaRegexp, RegexOptions.IgnoreCase))
                        {
                            dbSchemaNameBuilder.Append(schema.Reference.DatasetId);
                            length++;
                            nullBitmapBuffer.Append(true);

                            if (depth == GetObjectsDepth.DbSchemas)
                            {
                                dbSchemaTablesValues.Add(null);
                            }
                            else
                            {
                                dbSchemaTablesValues.Add(GetTableSchemas(
                                    depth, catalog, schema.Reference.DatasetId,
                                    tableNamePattern, tableTypes, columnNamePattern));
                            }
                        }
                    }
                }

                IArrowArray[] dataArrays = new IArrowArray[]
                {
                    dbSchemaNameBuilder.Build(),
                    dbSchemaTablesValues.BuildListArrayForType(new StructType(StandardSchemas.TableSchema)),
                };
                StandardSchemas.DbSchemaSchema.Validate(dataArrays);

                return new StructArray(
                    new StructType(StandardSchemas.DbSchemaSchema),
                    length,
                    dataArrays,
                    nullBitmapBuffer.Build());
            });
        }

        private StructArray GetTableSchemas(
            GetObjectsDepth depth,
            string catalog,
            string dbSchema,
            string? tableNamePattern,
            IReadOnlyList<string>? tableTypes,
            string? columnNamePattern)
        {
            return this.TraceActivity(activity =>
            {
                StringArray.Builder tableNameBuilder = new StringArray.Builder();
                StringArray.Builder tableTypeBuilder = new StringArray.Builder();
                List<IArrowArray?> tableColumnsValues = new List<IArrowArray?>();
                List<IArrowArray?> tableConstraintsValues = new List<IArrowArray?>();
                ArrowBuffer.BitmapBuilder nullBitmapBuffer = new ArrowBuffer.BitmapBuilder();
                int length = 0;

                string query = string.Format("SELECT * FROM `{0}`.`{1}`.INFORMATION_SCHEMA.TABLES",
                    Sanitize(catalog), Sanitize(dbSchema));

                if (tableNamePattern != null)
                {
                    query = string.Concat(query, string.Format(" WHERE table_name LIKE '{0}'", Sanitize(tableNamePattern)));
                    if (tableTypes?.Count > 0)
                    {
                        IEnumerable<string> sanitizedTypes = tableTypes.Select(x => Sanitize(x));
                        query = string.Concat(query, string.Format(" AND table_type IN ('{0}')", string.Join("', '", sanitizedTypes).ToUpper()));
                    }
                }
                else
                {
                    if (tableTypes?.Count > 0)
                    {
                        IEnumerable<string> sanitizedTypes = tableTypes.Select(x => Sanitize(x));
                        query = string.Concat(query, string.Format(" WHERE table_type IN ('{0}')", string.Join("', '", sanitizedTypes).ToUpper()));
                    }
                }

                BigQueryResults? result = ExecuteQuery(query, parameters: null);

                if (result != null)
                {
                    bool includeConstraints = true;

                    if (this.properties.TryGetValue(BigQueryParameters.IncludeConstraintsWithGetObjects, out string? includeConstraintsValue))
                    {
                        bool.TryParse(includeConstraintsValue, out includeConstraints);
                    }

                    foreach (BigQueryRow row in result)
                    {
                        tableNameBuilder.Append(GetValue(row["table_name"]));
                        tableTypeBuilder.Append(GetValue(row["table_type"]));
                        nullBitmapBuffer.Append(true);
                        length++;

                        if (depth == GetObjectsDepth.All && includeConstraints)
                        {
                            tableConstraintsValues.Add(GetConstraintSchema(
                                depth, catalog, dbSchema, GetValue(row["table_name"]), columnNamePattern));
                        }
                        else
                        {
                            tableConstraintsValues.Add(null);
                        }

                        if (depth == GetObjectsDepth.Tables)
                        {
                            tableColumnsValues.Add(null);
                        }
                        else
                        {
                            tableColumnsValues.Add(GetColumnSchema(catalog, dbSchema, GetValue(row["table_name"]), columnNamePattern));
                        }
                    }
                }

                IArrowArray[] dataArrays = new IArrowArray[]
                {
                    tableNameBuilder.Build(),
                    tableTypeBuilder.Build(),
                    tableColumnsValues.BuildListArrayForType(new StructType(StandardSchemas.ColumnSchema)),
                    tableConstraintsValues.BuildListArrayForType(new StructType(StandardSchemas.ConstraintSchema))
                };
                StandardSchemas.TableSchema.Validate(dataArrays);

                return new StructArray(
                    new StructType(StandardSchemas.TableSchema),
                    length,
                    dataArrays,
                    nullBitmapBuffer.Build());
            });
        }

        private StructArray GetColumnSchema(
            string catalog,
            string dbSchema,
            string table,
            string? columnNamePattern)
        {
            return this.TraceActivity(activity =>
            {
                StringArray.Builder columnNameBuilder = new StringArray.Builder();
                Int32Array.Builder ordinalPositionBuilder = new Int32Array.Builder();
                StringArray.Builder remarksBuilder = new StringArray.Builder();
                Int16Array.Builder xdbcDataTypeBuilder = new Int16Array.Builder();
                StringArray.Builder xdbcTypeNameBuilder = new StringArray.Builder();
                Int32Array.Builder xdbcColumnSizeBuilder = new Int32Array.Builder();
                Int16Array.Builder xdbcDecimalDigitsBuilder = new Int16Array.Builder();
                Int16Array.Builder xdbcNumPrecRadixBuilder = new Int16Array.Builder();
                Int16Array.Builder xdbcNullableBuilder = new Int16Array.Builder();
                StringArray.Builder xdbcColumnDefBuilder = new StringArray.Builder();
                Int16Array.Builder xdbcSqlDataTypeBuilder = new Int16Array.Builder();
                Int16Array.Builder xdbcDatetimeSubBuilder = new Int16Array.Builder();
                Int32Array.Builder xdbcCharOctetLengthBuilder = new Int32Array.Builder();
                StringArray.Builder xdbcIsNullableBuilder = new StringArray.Builder();
                StringArray.Builder xdbcScopeCatalogBuilder = new StringArray.Builder();
                StringArray.Builder xdbcScopeSchemaBuilder = new StringArray.Builder();
                StringArray.Builder xdbcScopeTableBuilder = new StringArray.Builder();
                BooleanArray.Builder xdbcIsAutoincrementBuilder = new BooleanArray.Builder();
                BooleanArray.Builder xdbcIsGeneratedcolumnBuilder = new BooleanArray.Builder();
                ArrowBuffer.BitmapBuilder nullBitmapBuffer = new ArrowBuffer.BitmapBuilder();
                int length = 0;

                string query = string.Format("SELECT * FROM `{0}`.`{1}`.INFORMATION_SCHEMA.COLUMNS WHERE table_name = '{2}'",
                    Sanitize(catalog), Sanitize(dbSchema), Sanitize(table));

                if (columnNamePattern != null)
                {
                    query = string.Concat(query, string.Format("AND column_name LIKE '{0}'", Sanitize(columnNamePattern)));
                }

                BigQueryResults? result = ExecuteQuery(query, parameters: null);

                if (result != null)
                {
                    foreach (BigQueryRow row in result)
                    {
                        columnNameBuilder.Append(GetValue(row["column_name"]));
                        ordinalPositionBuilder.Append((int)(long)row["ordinal_position"]);
                        remarksBuilder.Append("");

                        string dataType = ToTypeName(GetValue(row["data_type"]), out string suffix);

                        if ((dataType.StartsWith("NUMERIC") ||
                             dataType.StartsWith("DECIMAL") ||
                             dataType.StartsWith("BIGNUMERIC") ||
                             dataType.StartsWith("BIGDECIMAL"))
                            && !string.IsNullOrEmpty(suffix))
                        {
                            ParsedDecimalValues values = ParsePrecisionAndScale(suffix);
                            xdbcColumnSizeBuilder.Append(values.Precision);
                            xdbcDecimalDigitsBuilder.Append(Convert.ToInt16(values.Scale));
                        }
                        else
                        {
                            xdbcColumnSizeBuilder.AppendNull();
                            xdbcDecimalDigitsBuilder.AppendNull();
                        }

                        xdbcDataTypeBuilder.AppendNull();
                        xdbcTypeNameBuilder.Append(dataType);
                        xdbcNumPrecRadixBuilder.AppendNull();
                        xdbcNullableBuilder.AppendNull();
                        xdbcColumnDefBuilder.AppendNull();
                        xdbcSqlDataTypeBuilder.Append((short)ToXdbcDataType(dataType));
                        xdbcDatetimeSubBuilder.AppendNull();
                        xdbcCharOctetLengthBuilder.AppendNull();
                        xdbcIsNullableBuilder.Append(row["is_nullable"].ToString());
                        xdbcScopeCatalogBuilder.AppendNull();
                        xdbcScopeSchemaBuilder.AppendNull();
                        xdbcScopeTableBuilder.AppendNull();
                        xdbcIsAutoincrementBuilder.AppendNull();
                        xdbcIsGeneratedcolumnBuilder.Append(GetValue(row["is_generated"]).ToUpper() == "YES");
                        nullBitmapBuffer.Append(true);
                        length++;
                    }
                }
                IArrowArray[] dataArrays = new IArrowArray[]
                {
                    columnNameBuilder.Build(),
                    ordinalPositionBuilder.Build(),
                    remarksBuilder.Build(),
                    xdbcDataTypeBuilder.Build(),
                    xdbcTypeNameBuilder.Build(),
                    xdbcColumnSizeBuilder.Build(),
                    xdbcDecimalDigitsBuilder.Build(),
                    xdbcNumPrecRadixBuilder.Build(),
                    xdbcNullableBuilder.Build(),
                    xdbcColumnDefBuilder.Build(),
                    xdbcSqlDataTypeBuilder.Build(),
                    xdbcDatetimeSubBuilder.Build(),
                    xdbcCharOctetLengthBuilder.Build(),
                    xdbcIsNullableBuilder.Build(),
                    xdbcScopeCatalogBuilder.Build(),
                    xdbcScopeSchemaBuilder.Build(),
                    xdbcScopeTableBuilder.Build(),
                    xdbcIsAutoincrementBuilder.Build(),
                    xdbcIsGeneratedcolumnBuilder.Build()
                };
                StandardSchemas.ColumnSchema.Validate(dataArrays);

                return new StructArray(
                    new StructType(StandardSchemas.ColumnSchema),
                    length,
                    dataArrays,
                    nullBitmapBuffer.Build());
            });
        }

        private StructArray GetConstraintSchema(
            GetObjectsDepth depth,
            string catalog,
            string dbSchema,
            string table,
            string? columnNamePattern)
        {
            return this.TraceActivity(activity =>
            {
                StringArray.Builder constraintNameBuilder = new StringArray.Builder();
                StringArray.Builder constraintTypeBuilder = new StringArray.Builder();
                List<IArrowArray?> constraintColumnNamesValues = new List<IArrowArray?>();
                List<IArrowArray?> constraintColumnUsageValues = new List<IArrowArray?>();
                ArrowBuffer.BitmapBuilder nullBitmapBuffer = new ArrowBuffer.BitmapBuilder();
                int length = 0;

                string query = string.Format("SELECT * FROM `{0}`.`{1}`.INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE table_name = '{2}'",
                   Sanitize(catalog), Sanitize(dbSchema), Sanitize(table));

                BigQueryResults? result = ExecuteQuery(query, parameters: null);

                if (result != null)
                {
                    foreach (BigQueryRow row in result)
                    {
                        string constraintName = GetValue(row["constraint_name"]);
                        constraintNameBuilder.Append(constraintName);
                        string constraintType = GetValue(row["constraint_type"]);
                        constraintTypeBuilder.Append(constraintType);
                        nullBitmapBuffer.Append(true);
                        length++;

                        if (depth == GetObjectsDepth.All || depth == GetObjectsDepth.Tables)
                        {
                            constraintColumnNamesValues.Add(GetConstraintColumnNames(
                                catalog, dbSchema, table, constraintName));
                            if (constraintType.ToUpper() == "FOREIGN KEY")
                            {
                                constraintColumnUsageValues.Add(GetConstraintsUsage(
                                    catalog, dbSchema, table, constraintName));
                            }
                            else
                            {
                                constraintColumnUsageValues.Add(null);
                            }
                        }
                        else
                        {
                            constraintColumnNamesValues.Add(null);
                            constraintColumnUsageValues.Add(null);
                        }
                    }
                }

                IArrowArray[] dataArrays = new IArrowArray[]
                {
                    constraintNameBuilder.Build(),
                    constraintTypeBuilder.Build(),
                    constraintColumnNamesValues.BuildListArrayForType(StringType.Default),
                    constraintColumnUsageValues.BuildListArrayForType(new StructType(StandardSchemas.UsageSchema))
                };

                StandardSchemas.ConstraintSchema.Validate(dataArrays);

                return new StructArray(
                    new StructType(StandardSchemas.ConstraintSchema),
                    length,
                    dataArrays,
                    nullBitmapBuffer.Build());
            });
        }

        private StringArray GetConstraintColumnNames(
            string catalog,
            string dbSchema,
            string table,
            string constraintName)
        {
            return this.TraceActivity(activity =>
            {
                string query = string.Format("SELECT * FROM `{0}`.`{1}`.INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE table_name = '{2}' AND constraint_name = '{3}' ORDER BY ordinal_position",
               Sanitize(catalog), Sanitize(dbSchema), Sanitize(table), Sanitize(constraintName));

                StringArray.Builder constraintColumnNamesBuilder = new StringArray.Builder();

                BigQueryResults? result = ExecuteQuery(query, parameters: null);

                if (result != null)
                {
                    foreach (BigQueryRow row in result)
                    {
                        string column = GetValue(row["column_name"]);
                        constraintColumnNamesBuilder.Append(column);
                    }
                }

                return constraintColumnNamesBuilder.Build();
            });
        }

        private StructArray GetConstraintsUsage(
            string catalog,
            string dbSchema,
            string table,
            string constraintName)
        {
            return this.TraceActivity(activity =>
            {
                StringArray.Builder constraintFkCatalogBuilder = new StringArray.Builder();
                StringArray.Builder constraintFkDbSchemaBuilder = new StringArray.Builder();
                StringArray.Builder constraintFkTableBuilder = new StringArray.Builder();
                StringArray.Builder constraintFkColumnNameBuilder = new StringArray.Builder();
                ArrowBuffer.BitmapBuilder nullBitmapBuffer = new ArrowBuffer.BitmapBuilder();
                int length = 0;

                string query = string.Format("SELECT * FROM `{0}`.`{1}`.INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE WHERE constraint_name = '{2}'",
                   Sanitize(catalog), Sanitize(dbSchema), Sanitize(constraintName));

                BigQueryResults? result = ExecuteQuery(query, parameters: null);

                if (result != null)
                {
                    foreach (BigQueryRow row in result)
                    {
                        string constraint_catalog = GetValue(row["constraint_catalog"]);
                        string constraint_schema = GetValue(row["constraint_schema"]);
                        string table_name = GetValue(row["table_name"]);
                        string column_name = GetValue(row["column_name"]);

                        constraintFkCatalogBuilder.Append(constraint_catalog);
                        constraintFkDbSchemaBuilder.Append(constraint_schema);
                        constraintFkTableBuilder.Append(table_name);
                        constraintFkColumnNameBuilder.Append(column_name);

                        nullBitmapBuffer.Append(true);
                        length++;
                    }
                }

                IArrowArray[] dataArrays = new IArrowArray[]
                {
                    constraintFkCatalogBuilder.Build(),
                    constraintFkDbSchemaBuilder.Build(),
                    constraintFkTableBuilder.Build(),
                    constraintFkColumnNameBuilder.Build()
                };
                StandardSchemas.UsageSchema.Validate(dataArrays);

                return new StructArray(
                    new StructType(StandardSchemas.UsageSchema),
                    length,
                    dataArrays,
                    nullBitmapBuffer.Build());
            });
        }

        private string PatternToRegEx(string? pattern)
        {
            if (pattern == null)
                return ".*";

            StringBuilder builder = new StringBuilder("(?i)^");
            string convertedPattern = pattern.Replace("_", ".").Replace("%", ".*");
            builder.Append(convertedPattern);
            builder.Append("$");

            return builder.ToString();
        }

        private string ToTypeName(string type, out string suffix)
        {
            suffix = string.Empty;

            int index = type.IndexOf("(");
            if (index == -1)
                index = type.IndexOf("<");

            string dataType = index == -1 ? type : type.Substring(0, index);

            if (index > -1)
                suffix = type.Substring(dataType.Length);

            return dataType;
        }

        private XdbcDataType ToXdbcDataType(string type)
        {
            switch (type)
            {
                case "INTEGER" or "INT64":
                    return XdbcDataType.XdbcDataType_XDBC_INTEGER;
                case "FLOAT" or "FLOAT64":
                    return XdbcDataType.XdbcDataType_XDBC_FLOAT;
                case "BOOL" or "BOOLEAN":
                    return XdbcDataType.XdbcDataType_XDBC_BIT;
                case "STRING" or "GEOGRAPHY" or "JSON":
                    return XdbcDataType.XdbcDataType_XDBC_VARCHAR;
                case "BYTES":
                    return XdbcDataType.XdbcDataType_XDBC_BINARY;
                case "DATETIME":
                    return XdbcDataType.XdbcDataType_XDBC_DATETIME;
                case "TIMESTAMP":
                    return XdbcDataType.XdbcDataType_XDBC_TIMESTAMP;
                case "TIME":
                    return XdbcDataType.XdbcDataType_XDBC_TIME;
                case "DATE":
                    return XdbcDataType.XdbcDataType_XDBC_DATE;
                case "RECORD" or "STRUCT":
                    return XdbcDataType.XdbcDataType_XDBC_VARBINARY;
                case "NUMERIC" or "DECIMAL" or "BIGNUMERIC" or "BIGDECIMAL":
                    return XdbcDataType.XdbcDataType_XDBC_NUMERIC;
                default:

                    // in SqlDecimal, an OverflowException is thrown for decimals with scale > 28
                    // so the XDBC type needs to map the SqlDecimal type
                    int decimalMaxScale = 28;

                    if (type.StartsWith("NUMERIC("))
                    {
                        ParsedDecimalValues parsedDecimalValues = ParsePrecisionAndScale(type);

                        if (parsedDecimalValues.Scale <= decimalMaxScale)
                            return XdbcDataType.XdbcDataType_XDBC_DECIMAL;
                        else
                            return XdbcDataType.XdbcDataType_XDBC_VARCHAR;
                    }

                    if (type.StartsWith("BIGNUMERIC("))
                    {
                        if (bool.Parse(this.properties[BigQueryParameters.LargeDecimalsAsString]))
                        {
                            return XdbcDataType.XdbcDataType_XDBC_VARCHAR;
                        }
                        else
                        {
                            ParsedDecimalValues parsedDecimalValues = ParsePrecisionAndScale(type);

                            if (parsedDecimalValues.Scale <= decimalMaxScale)
                                return XdbcDataType.XdbcDataType_XDBC_DECIMAL;
                            else
                                return XdbcDataType.XdbcDataType_XDBC_VARCHAR;
                        }
                    }

                    if (type.StartsWith("STRUCT"))
                        return XdbcDataType.XdbcDataType_XDBC_VARCHAR;

                    return XdbcDataType.XdbcDataType_XDBC_UNKNOWN_TYPE;
            }
        }

        public override Schema GetTableSchema(string? catalog, string? dbSchema, string tableName)
        {
            return this.TraceActivity(activity =>
            {
                string query = string.Format("SELECT * FROM `{0}`.`{1}`.INFORMATION_SCHEMA.COLUMNS WHERE table_name = '{2}'",
                Sanitize(catalog), Sanitize(dbSchema), Sanitize(tableName));

                BigQueryResults? result = ExecuteQuery(query, parameters: null);

                List<Field> fields = new List<Field>();

                if (result != null)
                {
                    foreach (BigQueryRow row in result)
                    {
                        fields.Add(DescToField(row));
                    }
                }

                return new Schema(fields, null);
            });
        }

        private Field DescToField(BigQueryRow row)
        {
            Dictionary<string, string> metaData = new Dictionary<string, string>();
            metaData.Add("PRIMARY_KEY", "");
            metaData.Add("ORDINAL_POSITION", GetValue(row["ordinal_position"]));
            metaData.Add("DATA_TYPE", GetValue(row["data_type"]));

            Field.Builder fieldBuilder = SchemaFieldGenerator(GetValue(row["column_name"]), GetValue(row["data_type"]));
            fieldBuilder.Metadata(metaData);

            if (!GetValue(row["is_nullable"]).Equals("YES", StringComparison.OrdinalIgnoreCase))
            {
                fieldBuilder.Nullable(false);
            }

            fieldBuilder.Name(GetValue(row["column_name"]));

            return fieldBuilder.Build();
        }

        private string GetValue(object value)
        {
            switch (value)
            {
                case string sValue:
                    return sValue;
                default:
                    if (value != null)
                    {
                        string? sValue = value.ToString();
                        return sValue ?? string.Empty;
                    }
                    throw new InvalidOperationException($"Cannot parse {value}");
            }
        }

        private Field.Builder SchemaFieldGenerator(string name, string type)
        {
            int index = type.IndexOf("(");
            index = index == -1 ? type.IndexOf("<") : Math.Max(index, type.IndexOf("<"));
            string dataType = index == -1 ? type : type.Substring(0, index);

            return GetFieldBuilder(name, type, dataType, index);
        }

        private Field.Builder GetFieldBuilder(string name, string type, string dataType, int index)
        {
            Field.Builder fieldBuilder = new Field.Builder();
            fieldBuilder.Name(name);

            switch (dataType)
            {
                case "INTEGER" or "INT64":
                    return fieldBuilder.DataType(Int64Type.Default);
                case "FLOAT" or "FLOAT64":
                    return fieldBuilder.DataType(DoubleType.Default);
                case "BOOL" or "BOOLEAN":
                    return fieldBuilder.DataType(BooleanType.Default);
                case "STRING" or "GEOGRAPHY" or "JSON":
                    return fieldBuilder.DataType(StringType.Default);
                case "BYTES":
                    return fieldBuilder.DataType(BinaryType.Default);
                case "DATETIME":
                    return fieldBuilder.DataType(TimestampType.Default);
                case "TIMESTAMP":
                    return fieldBuilder.DataType(TimestampType.Default);
                case "TIME":
                    return fieldBuilder.DataType(Time64Type.Microsecond);
                case "DATE":
                    return fieldBuilder.DataType(Date32Type.Default);
                case "RECORD" or "STRUCT":
                    string fieldRecords = type.Substring(index + 1);
                    fieldRecords = fieldRecords.Remove(fieldRecords.Length - 1);
                    List<Field> nestedFields = new List<Field>();

                    foreach (string record in fieldRecords.Split(','))
                    {
                        string fieldRecord = record.Trim();
                        string fieldName = fieldRecord.Split(' ')[0];
                        string fieldType = fieldRecord.Split(' ')[1];
                        nestedFields.Add(SchemaFieldGenerator(fieldName, fieldType).Build());
                    }

                    return fieldBuilder.DataType(new StructType(nestedFields));
                case "NUMERIC" or "DECIMAL":
                    ParsedDecimalValues values128 = ParsePrecisionAndScale(type);
                    return fieldBuilder.DataType(new Decimal128Type(values128.Precision, values128.Scale));
                case "BIGNUMERIC" or "BIGDECIMAL":
                    ParsedDecimalValues values256 = ParsePrecisionAndScale(type);
                    return fieldBuilder.DataType(new Decimal256Type(values256.Precision, values256.Scale));
                case "ARRAY":
                    string arrayType = type.Substring(dataType.Length).Replace("<", "").Replace(">", "");
                    return GetFieldBuilder(name, type, arrayType, index);

                default: throw new InvalidOperationException($"{dataType} cannot be handled");
            }
        }

        private class ParsedDecimalValues
        {
            public int Precision { get; set; }
            public int Scale { get; set; }
        }

        private ParsedDecimalValues ParsePrecisionAndScale(string type)
        {
            if (string.IsNullOrWhiteSpace(type)) throw new ArgumentNullException(nameof(type));

            string[] values = type.Substring(type.IndexOf("(") + 1).TrimEnd(')').Split(",".ToCharArray());

            return new ParsedDecimalValues()
            {
                Precision = Convert.ToInt32(values[0]),
                Scale = Convert.ToInt32(values[1])
            };
        }

        public override IArrowArrayStream GetTableTypes()
        {
            StringArray.Builder tableTypesBuilder = new StringArray.Builder();
            tableTypesBuilder.AppendRange(BigQueryTableTypes.TableTypes);

            IArrowArray[] dataArrays = new IArrowArray[]
            {
                tableTypesBuilder.Build()
            };
            StandardSchemas.TableTypesSchema.Validate(dataArrays);

            return new BigQueryInfoArrowStream(StandardSchemas.TableTypesSchema, dataArrays);
        }

        public override AdbcStatement CreateStatement()
        {
            if (Credential == null)
            {
                throw new AdbcException("A credential must be set", AdbcStatusCode.Unauthenticated);
            }

            if (Client == null)
            {
                Client = Open();
            }

            BigQueryStatement statement = new BigQueryStatement(this);
            statement.Options = ParseOptions();
            return statement;
        }

        private Dictionary<string, string> ParseOptions()
        {
            Dictionary<string, string> options = new Dictionary<string, string>();

            string[] statementOptions = new string[] {
                BigQueryParameters.AllowLargeResults,
                BigQueryParameters.UseLegacySQL,
                BigQueryParameters.LargeDecimalsAsString,
                BigQueryParameters.LargeResultsDataset,
                BigQueryParameters.LargeResultsDestinationTable,
                BigQueryParameters.GetQueryResultsOptionsTimeout,
                BigQueryParameters.MaxFetchConcurrency,
                BigQueryParameters.StatementType,
                BigQueryParameters.StatementIndex,
                BigQueryParameters.EvaluationKind
            };

            foreach (string key in statementOptions)
            {
                if (this.properties.TryGetValue(key, out string? value))
                {
                    options[key] = value;
                }
            }

            return options;
        }

        public override void Dispose()
        {
            Client?.Dispose();
            Client = null;
            this.httpClient?.Dispose();
            this._fileActivityListener?.Dispose();
        }

        private static Regex sanitizedInputRegex = new Regex("^[a-zA-Z0-9_-]+");

        private string Sanitize(string? input)
        {
            if (string.IsNullOrEmpty(input))
                return string.Empty;

            bool isValidInput = sanitizedInputRegex.IsMatch(input);

            if (isValidInput)
            {
                return input!;
            }
            else
            {
                throw new AdbcException($"{input} is invalid", AdbcStatusCode.InvalidArgument);
            }
        }

        /// <summary>
        /// Gets the access token from the token endpoint.
        /// </summary>
        /// <param name="clientId"></param>
        /// <param name="clientSecret"></param>
        /// <param name="refreshToken"></param>
        /// <param name="tokenEndpoint"></param>
        /// <returns></returns>
        private string? GetAccessToken(string clientId, string clientSecret, string refreshToken, string tokenEndpoint)
        {
            string body = string.Format(
                "grant_type=refresh_token&client_id={0}&client_secret={1}&refresh_token={2}",
                clientId,
                clientSecret,
                Uri.EscapeDataString(refreshToken));

            HttpClient httpClient = new HttpClient();

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, tokenEndpoint);
            request.Headers.Add("Accept", "application/json");
            request.Content = new StringContent(body, Encoding.UTF8, "application/x-www-form-urlencoded");
            HttpResponseMessage response = httpClient.SendAsync(request).GetAwaiter().GetResult();
            string responseBody = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

            BigQueryTokenResponse? bigQueryTokenResponse = JsonSerializer.Deserialize<BigQueryTokenResponse>(responseBody);

            return bigQueryTokenResponse?.AccessToken;
        }

        /// <summary>
        /// Gets the access token from the sts endpoint.
        /// </summary>
        /// <param name="audience"></param>
        /// <param name="entraAccessToken"></param>
        /// <returns></returns>
        private string? TradeEntraIdTokenForBigQueryToken(string audience, string entraAccessToken)
        {
            try
            {
                var requestBody = new
                {
                    scope = BigQueryConstants.EntraIdScope,
                    subjectToken = entraAccessToken,
                    audience = audience,
                    grantType = BigQueryConstants.EntraGrantType,
                    subjectTokenType = BigQueryConstants.EntraSubjectTokenType,
                    requestedTokenType = BigQueryConstants.EntraRequestedTokenType
                };

                string json = JsonSerializer.Serialize(requestBody);
                StringContent content = new StringContent(json, Encoding.UTF8, "application/json");

                HttpResponseMessage response = this.httpClient.PostAsync(BigQueryConstants.EntraStsTokenEndpoint, content).GetAwaiter().GetResult();
                response.EnsureSuccessStatusCode();

                string responseBody = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

                BigQueryStsTokenResponse? bigQueryTokenResponse = JsonSerializer.Deserialize<BigQueryStsTokenResponse>(responseBody);

                return bigQueryTokenResponse?.AccessToken;
            }
            catch (Exception ex)
            {
                throw new AdbcException(
                    "Unable to obtain access token from BigQuery",
                    AdbcStatusCode.Unauthenticated,
                    ex);
            }
        }

        enum XdbcDataType
        {
            XdbcDataType_XDBC_UNKNOWN_TYPE = 0,
            XdbcDataType_XDBC_CHAR = 1,
            XdbcDataType_XDBC_NUMERIC = 2,
            XdbcDataType_XDBC_DECIMAL = 3,
            XdbcDataType_XDBC_INTEGER = 4,
            XdbcDataType_XDBC_SMALLINT = 5,
            XdbcDataType_XDBC_FLOAT = 6,
            XdbcDataType_XDBC_REAL = 7,
            XdbcDataType_XDBC_DOUBLE = 8,
            XdbcDataType_XDBC_DATETIME = 9,
            XdbcDataType_XDBC_INTERVAL = 10,
            XdbcDataType_XDBC_VARCHAR = 12,
            XdbcDataType_XDBC_DATE = 91,
            XdbcDataType_XDBC_TIME = 92,
            XdbcDataType_XDBC_TIMESTAMP = 93,
            XdbcDataType_XDBC_LONGVARCHAR = -1,
            XdbcDataType_XDBC_BINARY = -2,
            XdbcDataType_XDBC_VARBINARY = -3,
            XdbcDataType_XDBC_LONGVARBINARY = -4,
            XdbcDataType_XDBC_BIGINT = -5,
            XdbcDataType_XDBC_TINYINT = -6,
            XdbcDataType_XDBC_BIT = -7,
            XdbcDataType_XDBC_WCHAR = -8,
            XdbcDataType_XDBC_WVARCHAR = -9,
        }
    }
}
