using System;
using System.Linq;
using System.Reflection;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using QueryingDemo.Model;
using ScaffoldDemo;

namespace QueryingDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var dc = CreateDbContext())
            {
                Console.WriteLine("Select Sample");
                Console.WriteLine("-------------");
                foreach (var sample in DiscoverSamples())
                {
                    Console.WriteLine($"{sample.Number,-5}{sample.Title}");
                }
                Console.WriteLine();
                Console.Write("Enter Sample #: ");

                var number = int.TryParse(Console.ReadLine(), out var n) ? n : 0;
                var selectedSample = DiscoverSamples().SingleOrDefault(s => s.Number == number);
                if (selectedSample != null)
                {
                    Console.WriteLine();
                    Console.WriteLine();

                    selectedSample.Run(dc);
                    Console.ReadKey();
                }
            }
        }

        private static NorthwindContext CreateDbContext()
        {
            var dc = new NorthwindContext();
            var serviceProvider = dc.GetInfrastructure<IServiceProvider>();
            var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
            loggerFactory.AddProvider(new SqlQueryLoggerProvider());
            return dc;
        }

        private static IOrderedEnumerable<ISample> DiscoverSamples()
        {
            return typeof(Program).GetTypeInfo().Assembly.GetExportedTypes()
                .Where(t => typeof(ISample).IsAssignableFrom(t))
                .Where(t => t.IsClass)
                .Select(Activator.CreateInstance)
                .OfType<ISample>()
                .OrderBy(s => s.Number);
        }
    }
}
