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

using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;

namespace TestRootInterface
{
    public enum Gender
    {
        Male = 1,
        Female = 2
    }

    public class Address
    {
        public string Line1 { get; set; }
        public string City { get; set; }
        public string State { get; set; }
    }

    public interface ICodedValue
    {
        string Code { get; set; }
        string Name { get; set; }
    }

    public class Person : ICodedValue
    {
        [BsonId]
        public string Code { get; set; }
        public string Name { get; set; }
        public Gender Gender { get; set; }
        public DateTime BirthDate { get; set; }
    }

    public class Organization : ICodedValue
    {
        [BsonId]
        public string Code { get; set; }
        public string Name { get; set; }
        public Address Address { get; set; }
        public string Phone { get; set; }
    }

    public static class Program
    {
        public static void Main(string[] args)
        {
            try
            {
                BsonSerializer.LookupSerializer(typeof(Person));
                BsonSerializer.LookupSerializer(typeof(Organization));

                var server = MongoServer.Create("mongodb://localhost/database?safe=true");
                var database = server.GetDatabase("test");
                var collection = database.GetCollection<ICodedValue>("testrootinterface");

                if (!collection.Exists())
                {
                    var person = new Person { Code = "1234", Name = "John Doe", Gender = Gender.Male, BirthDate = new DateTime(2012, 1, 2, 0, 0, 0, DateTimeKind.Utc) };
                    collection.Insert(person);

                    var address = new Address { Line1 = "123 Main St", City = "New York", State = "NY" };
                    var organization = new Organization { Code = "5678", Name = "Org XYZ", Address = address, Phone = "1234" };
                    collection.Insert(organization);
                }

                foreach (var document in collection.FindAll())
                {
                    Console.WriteLine(document.GetType().FullName);
                    Console.WriteLine(document.ToJson());
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Unhandled exception:");
                Console.WriteLine(ex);
            }

            Console.WriteLine("Press Enter to continue");
            Console.ReadLine();
        }
    }
}