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

using System.Runtime.InteropServices;

namespace SNFMultiDLLExampleCsharp
{
    class SNFMultiDLLExample
    {

#region DLL Imports
        // Location of SNFMulti.dll.
        const string SNFMULTI_DLL = "..\\..\\..\\..\\..\\64bitDll\\SNFMulti.dll"; // Set CPU type to "Any CPU"
        //const string SNFMULTI_DLL = "..\\..\\..\\..\\..\\..\\64bitDll\\SNFMulti.dll"; // Set CPU type to "x64
        //const string SNFMULTI_DLL = "..\\..\\..\\..\\..\\..\\32bitDll\\SNFMulti.dll"; // Set CPU type to "x86"

        // int setThrottle(int Threads);                                                /* Set scan thread limit. */
        [DllImport(SNFMULTI_DLL, CharSet = CharSet.Auto, EntryPoint = "setThrottle", CallingConvention = CallingConvention.Winapi)]
        public static extern int setThrottle(int throttle);

        // int startupSNF(char* Path);                                                  /* Start SNF with configuration. */
        [DllImport(SNFMULTI_DLL, CharSet = CharSet.Auto, EntryPoint = "startupSNF", CallingConvention = CallingConvention.Winapi)]
        public static extern int startupSNF([MarshalAs(UnmanagedType.LPStr)] string Path);

        // int shutdownSNF();                                                           /* Shutdown SNF. */
        [DllImport(SNFMULTI_DLL, CharSet = CharSet.Auto, EntryPoint = "shutdownSNF", CallingConvention = CallingConvention.Winapi)]
        public static extern int shutdownSNF();

        // int testIP(unsigned long int IPToCheck);                                     /* Test the IP for a GBUdb range. */
        [DllImport(SNFMULTI_DLL, CharSet = CharSet.Auto, EntryPoint = "testIP", CallingConvention = CallingConvention.Winapi)]
        public static extern int testIP(ulong IPToCheck);

        // int scanBuffer(unsigned char* Bfr, int Length, char* Name, int Setup);       /* Scan msgBuffer, name, setup time. */
        [DllImport(SNFMULTI_DLL, CharSet = CharSet.Auto, EntryPoint = "scanBuffer", CallingConvention = CallingConvention.Winapi)]
        public static extern int scanBuffer(
            [MarshalAs(UnmanagedType.LPStr)] string Bfr,
            int Length,
            [MarshalAs(UnmanagedType.LPStr)] string Name,
            int Setup);

        // int scanFile(char* FilePath, int Setup);                                     /* Scan msgFile, setup time. */
        [DllImport(SNFMULTI_DLL, CharSet = CharSet.Auto, EntryPoint = "scanFile", CallingConvention = CallingConvention.Winapi)]
        public static extern int scanFile([MarshalAs(UnmanagedType.LPStr)] string Path, int Setup);

        // int getScanXHeaders(int ScanHandle, char** Bfr, int* Length);                /* Get result & XHeaders. */
        [DllImport(SNFMULTI_DLL, CharSet = CharSet.Auto, EntryPoint = "getScanXHeaders", CallingConvention = CallingConvention.Winapi)]
        public static extern int getScanXHeaders(int ScanHandle,
            out IntPtr Bfr,
            out int Length);

        // int getScanXMLLog(int ScanHandle, char** Bfr, int* Length);                  /* Get result & XML Log. */
        [DllImport(SNFMULTI_DLL, CharSet = CharSet.Auto, EntryPoint = "getScanXMLLog", CallingConvention = CallingConvention.Winapi)]
        public static extern int getScanXMLLog(int ScanHandle,
            out IntPtr Bfr,
            out int Length);

        // int getScanClassicLog(int ScanHandle, char** Bfr, int* Length);              /* Get result & Classic Log. */
        [DllImport(SNFMULTI_DLL, CharSet = CharSet.Auto, EntryPoint = "getScanClassicLog", CallingConvention = CallingConvention.Winapi)]
        public static extern int getScanClassicLog(int ScanHandle,
            out IntPtr Bfr,
            out int Length);

        // int getScanResult(int ScanHandle);                                           /* Get just the scan result. */
        [DllImport(SNFMULTI_DLL, CharSet = CharSet.Auto, EntryPoint = "getScanResult", CallingConvention = CallingConvention.Winapi)]
        public static extern int getScanResult(int ScanHandle);

        // int closeScan(int ScanHandle);                                               /* Close the scan result. */
        [DllImport(SNFMULTI_DLL, CharSet = CharSet.Auto, EntryPoint = "closeScan", CallingConvention = CallingConvention.Winapi)]
        public static extern int closeScan(int ScanHandle);


#endregion

        static void Main(string[] args)
        {
            string StartupFile = "C:\\SNFServer\\SNFServer.xml";
            System.Console.WriteLine("Hello, world!");
            int Result;

            Result = startupSNF(StartupFile);
            System.Console.WriteLine("startupSNF() returned:  " + Result);

            Result = setThrottle(4);
            System.Console.WriteLine("setThrottle():  " + Result);

            Result = testIP((ulong) 3 * 1000 * 1000 * 1000 + 32768);
            System.Console.WriteLine("testIP():  " + Result);

            string UglyText1 =
                "Received: from [213.93.213.84] (HELO uw-4b58d8528225.arnhem.chello.nl)\r\n" +
                "   by inbound.appriver.com (CommuniGate Pro SMTP 5.0.6)\r\n" +
                "From: \"somebody\" <somebody@someplace.com>\r\n" +
                "Subject: Nothing to see here\r\n" +
                "\r\n" +
                "So, this is a message eh?\r\n" +
                ".\r\n";

            int ScanHandle = 0;
            ScanHandle = scanBuffer(UglyText1, UglyText1.Length, "TestName", 0);
            System.Console.WriteLine("scanBuffer():  " + ScanHandle);

            Result = getScanResult(ScanHandle);
            System.Console.WriteLine("getScanResult():  " + Result);

            IntPtr XHeadersPtr = IntPtr.Zero;
            int XHeadersLength;
            Result = getScanXHeaders(ScanHandle, out XHeadersPtr, out XHeadersLength);
            System.Console.WriteLine("GetScanXHeaders():  " + Result);
            System.Console.WriteLine("XHeadersLength:  " + XHeadersLength);
            string XHeaders;
            XHeaders = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(XHeadersPtr, XHeadersLength);
            System.Console.WriteLine("XHeaders:  '" + XHeaders + "'");

            IntPtr XMLLogPtr = IntPtr.Zero;
            int XMLLogLength;
            Result = getScanXMLLog(ScanHandle, out XMLLogPtr, out XMLLogLength);
            System.Console.WriteLine("GetScanXMLLog():  " + Result);
            System.Console.WriteLine("XMLLogLength:  " + XMLLogLength);
            string XMLLog;
            XMLLog = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(XMLLogPtr, XMLLogLength);
            System.Console.WriteLine("XMLLog:  '" + XMLLog + "'");

            IntPtr ClassicLogPtr = IntPtr.Zero;
            int ClassicLogLength;
            Result = getScanClassicLog(ScanHandle, out ClassicLogPtr, out ClassicLogLength);
            System.Console.WriteLine("GetScanClassicLog():  " + Result);
            System.Console.WriteLine("ClassicLogLength:  " + ClassicLogLength);
            string ClassicLog;
            ClassicLog = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(ClassicLogPtr, ClassicLogLength);
            System.Console.WriteLine("ClassicLog:  '" + ClassicLog + "'");

            Result = closeScan(ScanHandle);
            System.Console.WriteLine("closeScan():  " + Result);
            
            string fileName = "junkmsg.txt";
            ScanHandle = scanFile(fileName, 4);
            System.Console.WriteLine("scanFile():  " + ScanHandle);

            Result = closeScan(ScanHandle);
            System.Console.WriteLine("closeScan():  " + Result);
   
            Result = shutdownSNF();
            System.Console.WriteLine("shutdownSNF():  " + Result);
        }
    }
}
