
Option Strict Off
Imports System
Imports System.Collections.Generic
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Assemblies
Imports System.IO
Imports System.Xml
Imports System.Data

Module NXJournal

    Public Property NxSyslog As LogFile = Nothing
    Public Property lw As ListingWindow = Nothing
    Private Property cmd As System.Data.Common.DbCommand = Nothing
    Private Property JobTemp_DP As String
    Private Property AllComponetsStructureNotUpdatedList As Dictionary(Of String, String) = New Dictionary(Of String, String)

    Private Const DB_PART_REV As String = "DB_PART_REV"

    Sub Main(ByVal args() As String)

        Dim UFSession As UFSession = UFSession.GetUFSession()
        Dim NXSession As NXOpen.Session = NXOpen.Session.GetSession()
        NxSyslog = NXSession.LogFile
        lw = Nothing

        Dim Accept As NXOpen.Update.FailureOption = 5
        NXSession.UpdateManager.SetDefaultUpdateFailureAction(Accept)

        JobTemp_DP = System.Environment.GetEnvironmentVariable("JobTemp_DP")
        Dim inputFile_DPNE As String = System.Environment.GetEnvironmentVariable("NXRefferencesGet_InputFile_DPNE")

        ' ###############################################
        ' ### Only for Testing ###
        'JobTemp_DP = "C:\Users\ideasadm\Desktop\NXReffTest\JobTemp"
        'inputFile_DPNE = "C:\Users\ideasadm\Desktop\NXReffTest\NXRefferencesGet_InputFile.txt"
        'exportRoot_DP = "J:\Mawera-Carve-Out\Examples\PLMP"
        'lw = NXSession.ListingWindow
        'ReplaceTCComponents = True
        'System.Environment.SetEnvironmentVariable("UGII_LOAD_OPTIONS", "D:\JobMgrL_T\JobClient\PLMS_ARASV_CSV3_Gen_M_00009_IMA\startup\NXNativ_load_options_loadallcomponentsandwave.def")
        ' ###############################################

        If IO.File.Exists(inputFile_DPNE) Then

            Try
                Dim inputFileLines As String() = IO.File.ReadAllLines(inputFile_DPNE)

                For Each line As String In inputFileLines

                    If line.Contains("|") Then
                        Dim objectCliNameForFileSys As String = line.Split("|"c)(0)
                        Dim NXPartFile_DPNE As String = line.Split("|"c)(1)
                        Dim NXReffXMLFile_DPNE As String = IO.Path.Combine(JobTemp_DP, objectCliNameForFileSys + ".xml")

                        NxSyslog.WriteLine("")
                        NxSyslog.WriteLine("")
                        NxSyslog.WriteLine("")
                        NxSyslog.WriteLine("##NXReffsGet:")
                        NxSyslog.WriteLine("##NXReffsGet: STARTs NX Refference extract for" + objectCliNameForFileSys)
                        NxSyslog.WriteLine("##NXReffsGet: NXPartFile_DPNE: " + NXPartFile_DPNE)
                        NxSyslog.WriteLine("##NXReffsGet: NXReffXMLFile_DPNE: " + NXReffXMLFile_DPNE)

                        ' get NX Refferences for each object
                        Call NXRefferencesGet(UFSession, NXSession, NxSyslog, NXPartFile_DPNE, NXReffXMLFile_DPNE, lw)

                        NxSyslog.WriteLine("##NXReffsGet: END NX Refference extract for" + objectCliNameForFileSys)

                    End If

                Next

            Catch ex As Exception
                NxSyslog.WriteLine("##NXReffsGet: EX in Method Main: " + ex.ToString())
            End Try

        End If

    End Sub

    ''' <summary>
    ''' function to get Nx Refferences and write it into an XML File
    ''' </summary>
    ''' <remarks>
    ''' #New: 3.1503;08.04.2021;S.Gueth
    ''' </remarks>
    Private Sub NXRefferencesGet(UFSession_p As UFSession,
                                 NXSession_p As NXOpen.Session,
                                 NxSyslog_p As LogFile,
                                 NXPart_DPNE_p As String,
                                 NXReffXMLFile_DPNE As String,
                                 Optional lw_p As ListingWindow = Nothing)

        Dim executionOK As Boolean = True
        Dim partOperationImportBuilder1 As NXOpen.PDM.PartOperationImportBuilder = Nothing
        Dim NXRefferences_Obj As NXRefferences_cls = New NXRefferences_cls
        Try

            If IO.File.Exists(NXPart_DPNE_p) Then
                Try
                    Dim compFileInfoObj As New IO.FileInfo(NXPart_DPNE_p)
                    If compFileInfoObj.IsReadOnly Then
                        compFileInfoObj.IsReadOnly = False
                        If lw_p IsNot Nothing Then lw_p.WriteLine("ReadOnly State changed for: " + NXPart_DPNE_p)
                        NxSyslog_p.WriteLine("##TCImportGetRefs: ReadOnly State changed for: " + NXPart_DPNE_p)
                    End If
                Catch ex As Exception
                End Try
            End If

            ' lw_p  = NXSession_p.ListingWindow
            If lw_p IsNot Nothing Then lw_p.Open()

            partOperationImportBuilder1 = NXSession_p.PdmSession.CreateImportOperationBuilder()
            partOperationImportBuilder1.DefaultAction = PDM.PartOperationImportBuilder.ExistingPartAction.Overwrite
            partOperationImportBuilder1.DefaultDestinationFolder = ":Newstuff"
            partOperationImportBuilder1.DefaultItemType = "AS5AEngPart"
            partOperationImportBuilder1.NumberingSource = PDM.PartOperationImportBuilder.NumberingSourceOption.OSFilename
            partOperationImportBuilder1.ConversionType = NXOpen.PDM.PartOperationImportBuilder.ConversionRule.AsIDandRevision
            partOperationImportBuilder1.IncludeDependentParts = False
            partOperationImportBuilder1.IncludeComponentParts = False
            Dim logicalobjects1() As NXOpen.PDM.LogicalObject
            partOperationImportBuilder1.CreateLogicalObjects(logicalobjects1)

            'Dim createalternateids1 As Boolean = Nothing
            'createalternateids1 = partOperationImportBuilder1.AssignAlternateIds

            Dim parts1(0) As String
            parts1(0) = NXPart_DPNE_p
            Dim errormsgs1() As String
            partOperationImportBuilder1.AddParts(parts1, errormsgs1)

            Dim logicalobjects2() As NXOpen.PDM.LogicalObject
            partOperationImportBuilder1.CreateLogicalObjects(logicalobjects2)

            Try
                Dim index As Integer = 0
                For Each logicalobjectCurr As PDM.LogicalObject In logicalobjects2
                    Dim sourceobjects() As NXOpen.NXObject
                    Dim nativePartLogicalObject As NXOpen.PDM.NativePartLogicalObject = CType(logicalobjectCurr, NXOpen.PDM.NativePartLogicalObject)
                    If lw_p IsNot Nothing Then lw_p.WriteLine("")
                    NxSyslog_p.WriteLine("")
                    If lw_p IsNot Nothing Then lw_p.WriteLine("Index: " + index.ToString)
                    NxSyslog_p.WriteLine("##TCImportGetRefs: Index: " + index.ToString)
                    Dim component As String = nativePartLogicalObject.GetInitialName
                    If lw_p IsNot Nothing Then lw_p.WriteLine("Component Name: " + component)
                    NxSyslog_p.WriteLine("##TCImportGetRefs: Component Name: " + component)

                    Dim isNameOnlyRef As Boolean = False

                    sourceobjects = nativePartLogicalObject.GetUserAttributeSourceObjects()
                    Dim sourceObjCurr As NXObject = sourceobjects(0)

                    For Each attrInfoCurr As NXObject.AttributeInformation In sourceObjCurr.GetUserAttributes()
                        Try
                            If attrInfoCurr.Title.ToUpper.Equals("TCIN_IMPORT_PART_STATE") Then
                                If attrInfoCurr.StringValue.Trim.ToUpper.Equals("Name Only".ToUpper) Then
                                    isNameOnlyRef = True
                                End If
                            End If
                            If lw_p IsNot Nothing Then lw_p.WriteLine("   Attr: " + attrInfoCurr.Title + " // Value: " + attrInfoCurr.StringValue)
                            NxSyslog_p.WriteLine("##TCImportGetRefs:    Attr: " + attrInfoCurr.Title + " // Value: " + attrInfoCurr.StringValue)
                        Catch ex As Exception
                        End Try
                    Next
                    index += 1

                    If lw_p IsNot Nothing Then lw_p.WriteLine("   is Name Only Ref: " + isNameOnlyRef.ToString)
                    NxSyslog_p.WriteLine("##TCImportGetRefs:    is Name Only Ref: " + isNameOnlyRef.ToString)

                    If IO.File.Exists(component) Then
                        Try
                            Dim compFileInfoObj As New IO.FileInfo(component)
                            If compFileInfoObj.IsReadOnly Then
                                compFileInfoObj.IsReadOnly = False
                                If lw_p IsNot Nothing Then lw_p.WriteLine("ReadOnly State changed for: " + component)
                                NxSyslog_p.WriteLine("##TCImportGetRefs: ReadOnly State changed for: " + component)
                            End If
                        Catch ex As Exception
                        End Try
                    End If

                    If isNameOnlyRef Then

                        NXRefferences_Obj.NXNamingRefferences.Add(component)

                    Else

                        Dim NXCompRefObj As New NXRefferences_cls.NXComponentRefference_cls
                        NXCompRefObj.Refference_DPNE = component
                        NXRefferences_Obj.NXComponentRefferences.Add(NXCompRefObj)

                    End If

                Next

                partOperationImportBuilder1.Destroy()

                'Dim resultFile As String = IO.Path.Combine(JobTemp_DP, "ImportResult.clone")
                'Dim prog As String = "D:\splmlocal\common\appl\nx1926\NXBIN\tcin_import.exe"
                'Dim args As String = "-u=bemig -p=Kg_5xfL6werf -g=dba -include_c=no -include_d=no -default_n=os_filename -conv=as_id_r -default_t=AS5AEngPart -default_a=overwrite -asse=" + NXPart_DPNE_p + " -s=" + resultFile

                'NxSyslog_p.WriteLine("")
                'NxSyslog_p.WriteLine("##TCImportGetRefs: Prog: " + prog)
                'NxSyslog_p.WriteLine("##TCImportGetRefs: Args: " + args)

                'Try
                '    Dim tcImportProcess As System.Diagnostics.Process = System.Diagnostics.Process.Start(prog, args)
                '    tcImportProcess.WaitForExit()
                'Catch ex As Exception
                '    NxSyslog_p.WriteLine("##TCImportGetRefs: " + ex.ToString)
                '    executionOK = False
                'End Try

            Catch ex As Exception
                NxSyslog_p.WriteLine("##TCImportGetRefs: " + ex.ToString)
                executionOK = False
            End Try


        Catch ex As Exception
            If lw_p IsNot Nothing Then lw_p.WriteLine(ex.ToString)
            NxSyslog_p.WriteLine("##TCImportGetRefs: " + ex.ToString)
            executionOK = False
        Finally
            Try
                partOperationImportBuilder1.Destroy()
            Catch ex As Exception
            End Try
        End Try

        ' write XML File
        If executionOK Then
            Try
                NXRefferences_Obj.WirteXMLFile(NXReffXMLFile_DPNE)
            Catch ex As Exception
            End Try
        End If

    End Sub


End Module

''' <summary>
''' Class that defines a NX Refference
''' </summary>
''' <remarks>
''' #New: 3.1503;11.05.2021;S.Gueth
''' #LUp: 3.1503;12.05.2021;S.Gueth
''' </remarks>
<Serializable>
Public Class NXRefferences_cls

    Public Property NXComponentRefferences As New List(Of NXComponentRefference_cls)
    Public Property NXNamingRefferences As New List(Of String)
    Public Property InterPartLinkRefferences As New List(Of String)
    Public Property WaveLinkRefferences As New List(Of String)
    Public Property PartFamilyRefferences As New List(Of PartFamilyRefference_cls)
    Public Property WasPartFamilyObject As Boolean = False
    Public Property PartFamilyTemplate As String = ""
    Public ReadOnly Property isPartFamilyMember As Boolean
        Get
            If String.IsNullOrEmpty(Me.PartFamilyTemplate) Then
                Return False
            Else
                Return True
            End If
        End Get
    End Property
    Public Property isPartFamilyMaster As Boolean = False

    ReadOnly Property RefferencesCount As Integer
        Get
            Return NXComponentRefferences.Count + InterPartLinkRefferences.Count + WaveLinkRefferences.Count + PartFamilyRefferences.Count
        End Get
    End Property

    Public Function WirteXMLFile(ByVal File_DPNE_p As String) As Boolean

        Dim fileInfo_obj As New IO.FileInfo(File_DPNE_p)
        If Not IO.Directory.Exists(fileInfo_obj.Directory.FullName) Then
            Try
                IO.Directory.CreateDirectory(fileInfo_obj.Directory.FullName)
            Catch ex As Exception
            End Try
        End If

        Try
            Dim xs As New System.Xml.Serialization.XmlSerializer(GetType(NXRefferences_cls))
            Using strWriter As New IO.StringWriter
                xs.Serialize(strWriter, Me)
                IO.File.WriteAllText(File_DPNE_p, strWriter.ToString)
                If IO.File.Exists(File_DPNE_p) Then
                    Return True
                End If
            End Using
        Catch ex As Exception
        End Try
        Return False
    End Function

    Public Shared Function LoadFromXMLFile(ByVal File_DPNE_p As String) As NXRefferences_cls
        Dim result As NXRefferences_cls = Nothing
        Try
            Dim xs As New System.Xml.Serialization.XmlSerializer(GetType(NXRefferences_cls))
            Using reader As TextReader = New StringReader(IO.File.ReadAllText(File_DPNE_p))
                result = CType(xs.Deserialize(reader), NXRefferences_cls)
            End Using
        Catch ex As Exception
            Throw ex
        End Try
        Return result
    End Function

    <Serializable>
    Public Class NXComponentRefference_cls
        Public Property Refference_DPNE As String = ""
        Public Property ItemID As String = ""
        Public Property RevID As String = ""
        Public Property CallOut As String = ""
        Public Property isReplaced As Boolean = False
        Public Property TCRefference As String = ""
        Public Property isSuppressed As Boolean = False
        Public Property asRefferenceOnly As Boolean = False
        Public Property UGEntityHandle As String = ""
        Public Property isNONGeometricComponent As Boolean = False
    End Class

    <Serializable>
    Public Class PartFamilyRefference_cls
        Public Property DBPartName As String = ""
        Public Property DBRevName As String = ""
    End Class

End Class

''' <summary>
''' class for databse connection
''' </summary>
''' <remarks>
''' #New: 3.1503;08.04.2021;S.Gueth
''' set following environmen tvaribales before executing nx journal:
''' DBProvider
''' OracleBin
''' SiteID
''' DBConnectionString
''' </remarks>
Public Class DBConnection_cls

    Private Shared Property dbConnection As Common.DbConnection = Nothing

    ''' <remarks>
    ''' #New: 3.1503;08.04.2021;S.Gueth
    ''' </remarks>
    Private Shared ReadOnly Property DBProvider As String
        Get
            Static DBProvider_stat = System.Environment.GetEnvironmentVariable("DBProvider")
            Return DBProvider_stat
        End Get
    End Property

    ''' <remarks>
    ''' #New: 3.1503;08.04.2021;S.Gueth
    ''' </remarks>
    Private Shared ReadOnly Property OracleBin As String
        Get
            Static OracleBin_stat = System.Environment.GetEnvironmentVariable("OracleBin")
            EnsureOracleBinIsInPath(OracleBin_stat)
            Return OracleBin_stat
        End Get
    End Property

    ''' <remarks>
    ''' #New: 3.1503;08.04.2021;S.Gueth
    ''' </remarks>
    Private Shared ReadOnly Property SiteID As String
        Get
            Static SiteID_stat = System.Environment.GetEnvironmentVariable("SiteID")
            Return SiteID_stat
        End Get
    End Property

    ''' <remarks>
    ''' #New: 3.1503;08.04.2021;S.Gueth
    ''' </remarks>
    Private Shared ReadOnly Property DBConnectionString As String
        Get
            Static DBConnectionString_stat = System.Environment.GetEnvironmentVariable("DBConnectionString")
            Return DBConnectionString_stat
        End Get
    End Property

    ''' <remarks>
    ''' #New: 3.1503;08.04.2021;S.Gueth
    ''' </remarks>
    Public Shared ReadOnly Property DBProviderFactory As Common.DbProviderFactory
        Get
            Static dbProviderFactory_stat As Common.DbProviderFactory = Common.DbProviderFactories.GetFactory(DBProvider)
            Return dbProviderFactory_stat
        End Get
    End Property

    ''' <summary>
    ''' function to get db connection object
    ''' </summary>
    ''' <remarks>
    ''' #New: 3.1503;08.04.2021;S.Gueth
    ''' </remarks>
    Private Shared Function GetConnection() As Common.DbConnection


        NxSyslog.WriteLine("##JournalDBConnection: Before connection to DB of TC.Site " + SiteID + " using DBProvider:" + DBProvider)
        If lw IsNot Nothing Then lw.WriteLine("Before connection to DB of TC.Site " + SiteID + " using DBProvider:" + DBProvider)

        Dim dbConnection_r As Common.DbConnection = DBProviderFactory.CreateConnection()
        dbConnection_r.ConnectionString = DBConnectionString

        Return dbConnection_r

    End Function

    ''' <summary>
    ''' generates the connection to the database
    ''' </summary>
    ''' <remarks>
    ''' #New: 3.1503;08.04.2021;S.Gueth
    ''' </remarks>
    Public Shared Sub ConnectToDB(ByRef cmd_p As Common.DbCommand)

        If dbConnection Is Nothing Then
            dbConnection = GetConnection()
        End If

        If cmd_p Is Nothing Then
            cmd_p = DBProviderFactory.CreateCommand()
            cmd_p.Connection = dbConnection
        End If

        If dbConnection Is Nothing Then
            NxSyslog.WriteLine("##JournalDBConnection: ERR: dbConnection Is Nothing")
            If lw IsNot Nothing Then lw.WriteLine("ERR: dbConnection Is Nothing")
        End If

        '-- open database connection
        If cmd_p.Connection.State <> ConnectionState.Open Then
            dbConnection.Open()
        End If

        If cmd_p.Connection.State <> ConnectionState.Open Then
            NxSyslog.WriteLine("##JournalDBConnection: ERR Connetion.State:" + cmd_p.Connection.State.ToString + "<>" + ConnectionState.Open.ToString)
            If lw IsNot Nothing Then lw.WriteLine("ERR: dbConnection Is Nothing")
        End If

    End Sub


    ''' <summary>
    ''' check if oracle bin db is in path
    ''' </summary>
    ''' <remarks>
    ''' #New: 3.1503;08.04.2021;S.Gueth
    ''' </remarks>
    Private Shared Sub EnsureOracleBinIsInPath(oracleBinDP_p As String)

        Dim pathEnvVar As String = Environment.GetEnvironmentVariable("PATH")
        If Not pathEnvVar.Contains(oracleBinDP_p) Then
            Environment.SetEnvironmentVariable("PATH", oracleBinDP_p + ";" + pathEnvVar)
        End If

    End Sub

End Class
