using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Operators
{
    // Listing 10-58
    public class CourseChoice
    {
        public int StudentId { get; set; }

        public string Category { get; set; }

        public int Number { get; set; }
    }

    class Examples58_62
    {
        public static void QueryWithJoin()
        {
            // Listing 10-59
            CourseChoice[] choices =
            {
                new CourseChoice { StudentId = 1, Category = "MAT", Number = 101 },
                new CourseChoice { StudentId = 1, Category = "MAT", Number = 102 },
                new CourseChoice { StudentId = 1, Category = "MAT", Number = 207 },
                new CourseChoice { StudentId = 2, Category = "MAT", Number = 101 },
                new CourseChoice { StudentId = 2, Category = "BIO", Number = 201 },
            };

            var studentsAndCourses = from choice in choices
                                     join course in Course.Catalog
                                       on new { choice.Category, choice.Number }
                                       equals new { course.Category, course.Number }
                                     select new { choice.StudentId, Course = course };

            foreach (var item in studentsAndCourses)
            {
                Console.WriteLine("Student {0} zapisał się na kurs {1}",
                    item.StudentId, item.Course.Title);
            }
        }

        private static CourseChoice[] choices =
        {
            new CourseChoice { StudentId = 1, Category = "MAT", Number = 101 },
            new CourseChoice { StudentId = 1, Category = "MAT", Number = 102 },
            new CourseChoice { StudentId = 1, Category = "MAT", Number = 207 },
            new CourseChoice { StudentId = 2, Category = "MAT", Number = 101 },
            new CourseChoice { StudentId = 2, Category = "BIO", Number = 201 },
        };

        public static void DirectJoin()
        {
            // Listing 10-60
            var studentsAndCourses = choices.Join(
                Course.Catalog,
                choice => new { choice.Category, choice.Number },
                course => new { course.Category, course.Number },
                (choice, course) => new { choice.StudentId, Course = course });


            foreach (var item in studentsAndCourses)
            {
                Console.WriteLine("Student {0} zapisał się na kurs {1}",
                    item.StudentId, item.Course.Title);
            }
        }

        public static void GroupedJoin()
        {
            // Listing 10-61
            var studentsAndCourses =
                from choice in choices
                join course in Course.Catalog
                  on new { choice.Category, choice.Number }
                  equals new { course.Category, course.Number } into courses
                select new { choice.StudentId, Courses = courses };

            foreach (var item in studentsAndCourses)
            {
                Console.WriteLine("Student {0} zapisał się na kursy: {1}",
                    item.StudentId,
                    string.Join(",", item.Courses.Select(course => course.Title)));
            }
        }

        public static void DirectGroupedJoin()
        {
            // Listing 10-62
            var studentsAndCourses = choices.GroupJoin(
                Course.Catalog,
                choice => new { choice.Category, choice.Number },
                course => new { course.Category, course.Number },
                (choice, courses) => new { choice.StudentId, Courses = courses });


            foreach (var item in studentsAndCourses)
            {
                Console.WriteLine("Student {0} zapisał się na kursy: {1}",
                    item.StudentId,
                    string.Join(",", item.Courses.Select(course => course.Title)));
            }
        }
    }
}
