'*************************************************************************
'
'      Author       : Esben Laursen (hyber@hyber.dk)
'      
'      Webpage      : http://www.hyber.dk or http://netsmsgw.sf.net
'
'      Notes        :
'
'      License      : This program is free software; you can redistribute
'                     it and/or modify it under the terms of the GNU
'                     General Public License as published by the Free
'                     Software Foundation version 2 of the License.
'
'*************************************************************************

Public Class netSMSgwd
    Dim WithEvents serPort As New IO.Ports.SerialPort
    Dim WithEvents msmtpd As smtpSRV.smtpd
    Dim WithEvents msmsd As smsTools.smsd
    Dim WithEvents mhttpd As netSMSgw.httpd
    Dim msmsStats As smsStatistics
    Dim WithEvents mtmrPhoneHome As Timers.Timer

    Public Enum CustomCommand
        TestPhoneConnection = 130
    End Enum


    Protected Overrides Sub OnStart(ByVal args() As String)
        ' Add code here to start your service. This method should set things
        ' in motion so your service can do its work.
        Try

            Call StartService()

        Catch ex As Exception
            Call AddToLog(gstrCriticalErr & ex.Message.ToString, netSMSgw.logUtils.LogLevels.Critical)
        End Try

    End Sub

    Private Sub CheckVer()
        Dim strct As netSMSgw.netSMSgwd.Utils.netSMSgwVersionCheck
        Dim util As New netSMSgw.netSMSgwd.Utils

        strct = util.CheckForNewVersion

        Call AddToLog(gstrCurVer & strct.CurrentVer, netSMSgw.logUtils.LogLevels.Info)
        Call AddToLog(gstrNewerVer & strct.NewestVer, netSMSgw.logUtils.LogLevels.Info)
        If strct.NewerAvailable Then Call AddToLog(gstrGotoWeb, netSMSgw.logUtils.LogLevels.Info)
    End Sub

    Public Function PhoneHomeStats() As Boolean

        Dim tmpStats As smsStatistics

        If IO.File.Exists(gSettings.statsFile) Then
            tmpStats = smsStatistics.Deserialize(gSettings.statsFile)
            Return PhoneHome(tmpStats, GetPhoneInfo)
        Else
            Return False
        End If

    End Function

    Public Sub StopQueue()
        msmsd.StopQueue()
    End Sub

    Public Sub StartQueue()
        msmsd.StartQueue()
    End Sub

    Public Sub StartService()

        Try

            Call AddToLog(gstrStart, netSMSgw.logUtils.LogLevels.Notice)
            'load settings
            gSettings = clsSettings.Deserialize(gstrSettingsPath)
            Call AddToLog(gstrLoadSet & gSettings.LogFile, netSMSgw.logUtils.LogLevels.Debug)

            'load stats
            If gSettings.statsSave Then
                msmsStats = smsStatistics.Deserialize(gSettings.statsFile)
                Call AddToLog(gstrLoadStats & gSettings.statsFile, netSMSgw.logUtils.LogLevels.Debug)

                'start phonehome
                If gSettings.statsAllowPhoneHome Then
                    mtmrPhoneHome = New Timers.Timer
                    mtmrPhoneHome.Interval = gSettings.statsPhoneHomeInterval * 1000
                    mtmrPhoneHome.Enabled = True
                End If
            End If

            'new version check
            If gSettings.CheckNewVersion Then Call CheckVer()


            'start services
            If gSettings.smtpEnabled Then Call StartSMTPd()
            If gSettings.httpEnabled Then Call StartHttpd()
            Call StartSMSd()



        Catch ex As Exception
            Call AddToLog(gstrCriticalErr & ex.Message.ToString, netSMSgw.logUtils.LogLevels.Critical)
        End Try

    End Sub

    Private Sub StartHttpd()
        mhttpd = New netSMSgw.httpd

        If Not mhttpd.IsSupported Then

            gSettings.httpEnabled = False
            Call AddToLog(gstrHttpdNotSupported, logUtils.LogLevels.Critical)
            clsSettings.Serialize(gstrSettingsPath, gSettings)
            Exit Sub
        End If


        Dim httpThread As New Threading.Thread(AddressOf mhttpd.StartHTTPd)
        Dim colUsers As New Collection

        'set settings for httpd service
        mhttpd.ListenOnURL = gSettings.httpListenDomain
        mhttpd.ListenPort = gSettings.httpPort
        If gSettings.httpEnableUsers Then mhttpd.DisableUserAuth = False Else mhttpd.DisableUserAuth = True
        mhttpd.UserCollection = gSettings.httpUsersDB

        'start thread
        httpThread.Start()
    End Sub

    Public Sub StopService()

        Try
            'write to log that we are stopping everything
            Call AddToLog(gstrStop, netSMSgw.logUtils.LogLevels.Notice)


            'stop services.
            Call StopSMSd()
            If gSettings.smtpEnabled Then msmtpd.srvStop()
            If gSettings.httpEnabled Then mhttpd.StopHTTPd()

            'save stats if settings says we want to save it :-)
            If gSettings.statsSave Then netSMSgw.netSMSgwd.smsStatistics.Serialize(gSettings.statsFile, msmsStats)

            'stop phonehome timer.
            If Not IsNothing(mtmrPhoneHome) Then mtmrPhoneHome.Enabled = False


        Catch ex As Exception
            Call AddToLog(gstrCriticalErr & ex.Message.ToString, netSMSgw.logUtils.LogLevels.Critical)
        End Try

    End Sub

    Protected Overrides Sub OnStop()
        ' Add code here to perform any tear-down necessary to stop your service.
        Try

            Call StopService()

        Catch ex As Exception
            Call AddToLog(gstrCriticalErr & ex.Message.ToString, netSMSgw.logUtils.LogLevels.Critical)
        End Try

    End Sub


    Private Sub StartSMTPd()

        Try
            Dim col As New Collection
            Dim str As String

            msmtpd = New smtpSRV.smtpd(gSettings.smtpListenPort, gSettings.smtpListenIPAdr)
            msmtpd.ServerName = gSettings.smtpServerName

            'we cant convert the "xmlCollection" to a regular collection..
            For Each str In gSettings.smtpHosts
                col.Add(str)
            Next

            msmtpd.smtpHosts = col
            msmtpd.AllowAllPrDefault = gSettings.smtpAllowAll


            Dim thread As New System.Threading.Thread(AddressOf msmtpd.srvStart)
            thread.Start()

        Catch ex As Exception
            Call AddToLog(gstrCriticalErr & ex.Message.ToString, netSMSgw.logUtils.LogLevels.Critical)
        End Try

    End Sub

    Private Sub StartSMSd()

        Try

            msmsd = New smsTools.smsd(gSettings.smsComPort)

            With msmsd
                .BaudRate = gSettings.smsBaudRate
                .DTR = gSettings.smsDTR
                .Parity = gSettings.smsParity
                .RTS = gSettings.smsRTS
                .WaitBetweenSMS = gSettings.smsWaitSec
                .StopBits = gSettings.smsStopBits
                .HandShake = gSettings.smsHandShake
                .DataBits = gSettings.smsDataBits


                .StartTime = gSettings.smsPeekHourStart
                .EndTime = gSettings.smsPeekHourEnd
                .RescrictTime = gSettings.smsRestrictTime
                .IgnoreTimeRestrictOnHighPriority = gSettings.smsIgnoreRestrictionOnHighPriority

                .FakeIt = gSettings.FakeIt


                .StartQueue()

            End With



        Catch ex As Exception
            Call AddToLog(gstrCriticalErr & ex.Message.ToString, netSMSgw.logUtils.LogLevels.Critical)
        End Try

    End Sub

    Private Sub StopSMSd()
        'todo: we should really, close smsd queue before we close down. now everything in queue is deleted!
        msmsd.StopQueue()
    End Sub

    Public Function TestPhoneConnection() As String
        Try
            Dim str As String
            'msmsd = New smsTools.smsd(gSettings.smsComPort)

            With msmsd
                .BaudRate = gSettings.smsBaudRate
                .DTR = gSettings.smsDTR
                .Parity = gSettings.smsParity
                .RTS = gSettings.smsRTS
                .WaitBetweenSMS = gSettings.smsWaitSec
                .StopBits = gSettings.smsStopBits
                .HandShake = gSettings.smsHandShake
                .DataBits = gSettings.smsDataBits
                .TimeOutReadMs = gSettings.smsTimeOutReadMs
                .TimeOutWriteMs = gSettings.smsTimeOutWriteMs

                'pause operation.
                .StopQueue(True)
            End With

            str = msmsd.TestPhoneConnection()

            If Not str = "" Then
                MsgBox("Success!!!" & vbCrLf & "Returned: " & vbCrLf & vbCrLf & str, MsgBoxStyle.Information, "Data returned")
            Else
                MsgBox("Failed!! :-(" & vbCrLf & vbCrLf & "Nothing was returned from the phone/modem, please check the COM settings!", MsgBoxStyle.Exclamation, "Failed!")
            End If

            'resume operation again.
            Call msmsd.StartQueue()
            Return str

        Catch ex As Exception
            Call AddToLog(gstrCriticalErr & ex.Message.ToString, netSMSgw.logUtils.LogLevels.Critical)
            Return ex.Message.ToString
        End Try

    End Function


    Private Sub smsd_Log(ByVal pstrLog As String, ByVal penuLogLevel As smsTools.smsd.LogLevels) Handles msmsd.Log
        Call AddToLog(pstrLog, penuLogLevel)
    End Sub

    Private Sub smtpd_Log(ByVal pstrLog As String, ByVal penuLoglevel As netSMSgw.logUtils.LogLevels) Handles msmtpd.Log
        Call AddToLog(pstrLog, penuLoglevel)
    End Sub

    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.

    End Sub

    Private Sub mhttpd_GotSMSMsg(ByVal sms As smsMsg) Handles mhttpd.GotSMSMsg
        msmsd.AddToQueue(sms)
    End Sub

    Private Sub mhttpd_Log(ByVal pstrLog As String, ByVal penuLogLevel As logUtils.LogLevels) Handles mhttpd.Log
        Call AddToLog(pstrLog, penuLogLevel)
    End Sub

    Private Sub msmtpd_ReturnSMSs(ByVal pcolMsgs As Microsoft.VisualBasic.Collection) Handles msmtpd.ReturnSMSs
        msmsd.AddToQueue(pcolMsgs)
    End Sub

    Private Sub msmsd_smsSent(ByVal sms As smsMsg, ByVal Success As Boolean) Handles msmsd.smsSent

        If gSettings.statsSave Then
            msmsStats.AddEntry(sms, Now, Success)
            smsStatistics.Serialize(gSettings.statsFile, msmsStats)
        End If

    End Sub

    Public Function GetPhoneInfo()

        Dim strctInf As New netSMSgw.smsTools.smsd.PhoneInfo

TryAgain:
        'pause queue
        Call msmsd.StopQueue(True)

        'if there is something in queue, wait for 8 secs for the sms send
        If msmsd.IsQueueRunning Then GoTo TryAgain


        msmsd.TimeOutReadMs = gSettings.smsTimeOutReadMs
        msmsd.TimeOutWriteMs = gSettings.smsTimeOutWriteMs

        strctInf = msmsd.GetPhoneInfo()

        'resume queue
        Call msmsd.StartQueue()

        Return strctInf

    End Function

    Protected Overrides Sub OnCustomCommand(ByVal pintCmd As Integer)

        MsgBox("TEST")

        Select Case pintCmd
            Case CustomCommand.TestPhoneConnection
                Call TestPhoneConnection()
            Case Else
                Call AddToLog(gstrCustomCmd, logUtils.LogLevels.Warnings)
        End Select

    End Sub

    Private Sub mtmrPhoneHome_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles mtmrPhoneHome.Elapsed
        Dim bol As Boolean = False
        If Not IsNothing(msmsStats) Then
            bol = PhoneHome(msmsStats, GetPhoneInfo)
        End If
        Call AddToLog(gstrPhoneHome & bol.ToString, logUtils.LogLevels.Info)
    End Sub
End Class
