using System;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Text;
using smo = Microsoft.SqlServer.Management.Smo;
namespace UDTScript
{
    class Program
    {
        static void Main(string[] args)
        {
            smo.Server local = new smo.Server();
            smo.Scripter sptr = new smo.Scripter(local);
            smo.Database myUDA = local.Databases["MyUDA"];
            List<smo.SqlSmoObject> list = new List<smo.SqlSmoObject>();
            foreach (smo.UserDefinedFunction udf in 
                myUDA.UserDefinedFunctions)
            {
                if (udf.ImplementationType == 
                    smo.ImplementationType.SqlClr)
                {
                    Predicate<smo.SqlSmoObject> p =
                        delegate(smo.SqlSmoObject match)
                        {
                            if(match is smo.SqlAssembly)
                            {
                                return ((smo.SqlAssembly)match).Name == udf.AssemblyName;
                            }
                            return false;
                        };
                    if (null == list.Find(p))
                    {
                        list.Add(myUDA.Assemblies[udf.AssemblyName]);
                    }
                    list.Add(udf);
                }
            }
            Console.WriteLine("===================");
            smo.DependencyTree tree = sptr.DiscoverDependencies(list.ToArray(), false);
            StringCollection sc1 = sptr.ScriptWithList(sptr.WalkDependencies(tree));
            foreach (string s in sc1)
            {
                //Console.WriteLine(s);
            }
            Console.WriteLine("===================");
            sc1 = sptr.ScriptWithList(list.ToArray());
            foreach (string s in sc1)
            {
                Console.WriteLine(s);
            }

            int direction = -1;
            Comparison<smo.SqlSmoObject> c = delegate (smo.SqlSmoObject s1, smo.SqlSmoObject s2)
            {
                if (s1.GetType() == s2.GetType())
                    return 0;
                else
                    if (s1 is smo.SqlAssembly)
                        return -1 * direction;
                return 1 * direction;

            };
            list.Sort(c);
            smo.ProgressReportEventHandler rpt = 
                delegate(Object sender, smo.ProgressReportEventArgs rptargs)
                {
                    //Console.Write("+");
                };
            sptr.ScriptingProgress += rpt;
            
            sptr.Options.ScriptDrops = true;
            StringCollection script = sptr.Script(list.ToArray());
            sptr.Options.ScriptDrops = false;
            
            direction = 1;
            list.Sort(c);
            foreach(String s in script)
            {
                Console.WriteLine(s);
            }
            script = sptr.Script(list.ToArray());
            foreach (String s in script)
            {
                Console.WriteLine(s);
            }

        }

    }
}
