text: // Copyright (c) .NET Foundation. All rights reserved.
  // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using Microsoft.EntityFrameworkCore.Infrastructure;
  using Microsoft.EntityFrameworkCore.Sqlite.Internal;
  using Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal;
  using Microsoft.EntityFrameworkCore.Storage;
  using Microsoft.Extensions.DependencyInjection;
  
  namespace Microsoft.EntityFrameworkCore.Sqlite.Infrastructure.Internal
  {
      /// <summary>
      ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
      ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
      ///     any release. You should only use it directly in your code with extreme caution and knowing that
      ///     doing so can result in application failures when updating to a new Entity Framework Core release.
      /// </summary>
      public class SqliteNetTopologySuiteOptionsExtension : IDbContextOptionsExtension
      {
          private DbContextOptionsExtensionInfo _info;
  
          /// <summary>
          ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
          ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
          ///     any release. You should only use it directly in your code with extreme caution and knowing that
          ///     doing so can result in application failures when updating to a new Entity Framework Core release.
          /// </summary>
          public virtual DbContextOptionsExtensionInfo Info
              => _info ??= new ExtensionInfo(this);
  
          /// <summary>
          ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
          ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
          ///     any release. You should only use it directly in your code with extreme caution and knowing that
          ///     doing so can result in application failures when updating to a new Entity Framework Core release.
          /// </summary>
          public virtual void ApplyServices(IServiceCollection services)
              => services.AddEntityFrameworkSqliteNetTopologySuite();
  
          /// <summary>
          ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
          ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
          ///     any release. You should only use it directly in your code with extreme caution and knowing that
          ///     doing so can result in application failures when updating to a new Entity Framework Core release.
          /// </summary>
          public virtual void Validate(IDbContextOptions options)
          {
              var internalServiceProvider = options.FindExtension<CoreOptionsExtension>()?.InternalServiceProvider;
              if (internalServiceProvider != null)
              {
                  using var scope = internalServiceProvider.CreateScope();
                  var plugins = scope.ServiceProvider.GetService<IEnumerable<IRelationalTypeMappingSourcePlugin>>();
                  if (plugins?.Any(s => s is SqliteNetTopologySuiteTypeMappingSourcePlugin) != true)
                  {
                      throw new InvalidOperationException(SqliteNTSStrings.NTSServicesMissing);
                  }
              }
          }
  
          private sealed class ExtensionInfo : DbContextOptionsExtensionInfo
          {
              public ExtensionInfo(IDbContextOptionsExtension extension)
                  : base(extension)
              {
              }
  
              private new SqliteNetTopologySuiteOptionsExtension Extension
                  => (SqliteNetTopologySuiteOptionsExtension)base.Extension;
  
              public override bool IsDatabaseProvider
                  => false;
  
              public override string LogFragment
                  => "using NetTopologySuite ";
  
              public override long GetServiceProviderHashCode()
                  => 0;
  
              public override void PopulateDebugInfo(IDictionary<string, string> debugInfo)
                  => debugInfo["NetTopologySuite"] = "1";
          }
      }
  }
  