using System;

using System.IO;

using System.Xml;

using System.Text;

using System.Diagnostics;

using System.Collections.Specialized;

using System.Collections.Generic;

 

using Colligo.WML;

using Colligo.WML.Sync;

using Colligo.Properties;

 

namespace Colligo.Extensions

{

 

    public class FileWatcher

    {

        const string DEVELOPER_KEY = "0K1Q8-075YJ-Q8FEN-GS64P-45JXG";

 

        public const String FOLDER_SETTINGS_FILENAME = "contributorsettings.xml";

 

        private List<FileSystemWatcher> m_fsw = new List<FileSystemWatcher>();

        IWebManager m_colligoWebMgr = null;

        SyncManager m_colligoSyncMgr = null;

 

        static void Main (String[] args)

        {

            new FileWatcher().Run(args);

        }

 

        public void Run(String[] args)

        {

            Trace.Listeners.Add(new ConsoleTraceListener());

 

            try

            {

                m_colligoWebMgr = WMLApp.GetWebManager();

                m_colligoWebMgr.Initialize(DEVELOPER_KEY);

 

                m_colligoSyncMgr = SyncManager.GetInstance();

                m_colligoSyncMgr.Initialize();

 

                initializeWatchers(args);

 

                Console.WriteLine("Press any key to stop");

                Console.ReadKey();

            }

            catch (Exception except)

            {

                Console.WriteLine("Exception: " + except);

            }

            finally

            {

                if (m_colligoSyncMgr != null)

                {

                    m_colligoSyncMgr.Shutdown();

                }

                if (m_colligoWebMgr != null)

                {

                    m_colligoWebMgr.Shutdown();

                }

            }

 

        }

 

        private void initializeWatchers(String[] paths)

        {

            try

            {

                foreach (String path in paths)

                {

                    if (Directory.Exists(path))

                    {

                        FileSystemWatcher fsw = new FileSystemWatcher();

                        fsw.Path = path;

                        fsw.Created += new FileSystemEventHandler(fswCreated);

                        fsw.EnableRaisingEvents = true;

                        m_fsw.Add(fsw);

                        Trace.WriteLine("Added Watcher for path: " + path);

                    }

                }

            }

            catch { }

        }

 

        private void getFolderSettings(String filename, out String siteUrl, out String contentTypeName, out String listName, out String folderPath, out NameValueCollection metadata)

        {

            siteUrl = String.Empty;

            contentTypeName = String.Empty;

            listName = String.Empty;

            folderPath = String.Empty;

            metadata = new NameValueCollection();

 

            FileInfo fi = new FileInfo(filename);

            String fileFolder = fi.DirectoryName;

 

            String configFile = String.Format("{0}\\{1}", fileFolder, FOLDER_SETTINGS_FILENAME);

            if (File.Exists(configFile))

            {

                try

                {

                    XmlDocument doc = new XmlDocument();

                    doc.Load(configFile);

                   

                    XmlNode ndList = doc.SelectSingleNode("/Settings/List");

                    siteUrl = ndList.Attributes["SiteUrl"].InnerText;

                    listName = ndList.Attributes["Name"].InnerText;

 

                    XmlNode ndContentType = doc.SelectSingleNode("/Settings/ContentType");

                    contentTypeName = ndContentType.Attributes["Name"].InnerText;

 

                    if (ndList.Attributes["FolderPath"] != null)

                        folderPath = ndList.Attributes["FolderPath"].InnerText;

                    else

                        folderPath = String.Empty;

 

                    foreach (XmlNode nd in doc.SelectNodes("Settings/Metadata/*"))

                    {

                        metadata.Add(nd.Attributes["Name"].Value, nd.Attributes["Value"].Value);

                    }

                }

                catch (Exception ex)

                {

                    Trace.WriteLine("Exception:\n" + ex);

                }

            }

        }

 

        private bool isProcessableFile(String filename)

        {

            try

            {

                FileInfo fi = new FileInfo(filename);

                if (!fi.Exists)

                    return false;

                else if ((fi.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)

                    return false;

                else if (fi.Name.Equals(FOLDER_SETTINGS_FILENAME))

                    return false;

            }

            catch (Exception ex)

            {

                Trace.WriteLine("Exception:\n" + ex);

                return false;

            }

           

            return true;

        }

 

        private bool uploadFile(String siteUrl, String contentTypeName, String listName, String folderPath, String filename, NameValueCollection metadata)

        {

            try

            {

                IWeb web = m_colligoWebMgr.GetWebByUrl(siteUrl);

                if (web == null) return false;

 

                IList list = null;

                ListCollection lists = web.GetListsOfType(BaseType.DocumentLibrary);

                foreach (IList l in lists)

                {

                    if (l.Name.Equals(listName))

                    {

                        list = l;

                        break;

                    }

                }

                if (list == null) return false;

 

                IContentType contentType = null;

                foreach (IContentType ct in list.StandardContentTypes)

                {

                    if (ct.Name.Equals(contentTypeName))

                    {

                        contentType = ct;

                        break;

                    }

                }

 

                IListItem folder = folderPath.Length > 0 ? list.GetListItemByPath(folderPath) : null;

 

                using (list.GetMultipleUpdateLock())

                {

                    Trace.WriteLine("\tImporting File");

                    IListItem item = list.ImportFile(folder, filename, null, true);

 

                    if (item == null) return false;

 

                    if (contentType != null)

                        item.ContentType = contentType;

 

                    foreach (String key in metadata.Keys)

                    {

                        item.SetProperty(key, metadata[key]);

                        Trace.WriteLine("\tSetting Property. Name='" + key + "'\tValue='" + metadata[key] + "'");

                    }

                    item.Update();

                    Trace.WriteLine("\tImport Complete.\n");

                }

                return true;

            }

            catch (Exception ex)

            {

                System.Diagnostics.Trace.WriteLine(ex.ToString());

                return false;

            }

        }

 

        void fswCreated(object sender, FileSystemEventArgs e)

        {

            if (!isProcessableFile(e.FullPath)) return;

 

            Trace.WriteLine("Item Created: " + e.Name);

 

           

            String siteUrl;

            String contentTypeName;

            String listName;

            String folderPath;

            NameValueCollection metadata;

            getFolderSettings(e.FullPath, out siteUrl, out contentTypeName, out listName, out folderPath, out metadata);

 

            if (uploadFile(siteUrl, contentTypeName, listName, folderPath, e.FullPath, metadata))

            {

                File.Delete(e.FullPath);

            }

        }

 

    }

}