import riegl.rdb as rdb
import os
import sys
import json
import time
import json

# Create text file of points from the rdbx individual pofx files
def SearchRDBXForWaveForm(rdbPath):
    count = 0
    pathsize = os.path.getsize(rdbPath)
    rt= ""
    response = ""
    liwf = []
    with rdb.rdb_open(rdbPath) as rdbopen:
        for points in rdbopen.select("(riegl.id == 10)" ): 
            print(points.riegl_waveform_available[0])
          #  liwf.append(points.riegl_waveform_available[0])
            rt = points.riegl_waveform_available[0]
            break

        if rt == 1:
            response = "Found at least 1 waveform!"
        else:
            response = "No waveforms"
    sys.stdout.write(response)

# Reads rdbx transaction list and extracts info about the actions run on the file.
def SearchRDBXTransactions(rdbPathli):
    tic = time.perf_counter()
    rdbPath = rdbPathli[-1]
    with rdb.rdb_open(rdbPath) as rdbopen:
        pointCloud = rdbopen.point_attributes.pointcloud
        transactionlist  = pointCloud.transactions.list()
        
        rt = 0
        ground = 0
        build = 0 
        colour = 0
        isoPoint = 0
        delete = 0
        noiseRemove = 0
        setli = ""
        pointsclassified = 0
        classli = []
        projType = ""
        for itemIndex in transactionlist:
            details = pointCloud.transactions.details(itemIndex)
            if pointsclassified == 0:      
                # Classification
                if details.title == "Point classification":
                    setli = details.settings
                    pointsclassified += 1
                    j = json.loads(setli)

                    # check hydrotools classifier

                    SelectedPointFilters = j["classification_method"]["settings"]
                    #"searchRadius=2;maxNeighCount=4;targetClassId=18;"
                    if SelectedPointFilters != "":
                        targetclassID = SelectedPointFilters.split(";")
                        classli.append(int([classcode for classcode in targetclassID if "targetClassId" in classcode][0].split("=")[1]))
            else:
                pass

            if ground == 0:
                if details.title == "Ground Classification":
                    ground += 1         
            else:
                pass

            if build == 0:                 
                if details.title == "Building Classification":
                    build += 1    
            else:
                pass

            if colour ==0:
                #if details.title == "Colorizing points from images":
                if details.title.__contains__("Colorizing points from images"):
                    colour += 1
            else:
                pass

            #Isolated points classified is the first step in noise removal. It classifies a class code of 64 by default.
            if details.comments.__contains__("Isolated Point Classifier"):
                isoPoint += 1
  
            if details.title.__contains__("Delete points"):
                delete += 1        
                 
           
        datacreated = pointCloud.transactions.details(transactionlist[0]).start
        lastmod = pointCloud.transactions.details(transactionlist[-1]).stop

        pcinfostr = pointCloud.meta_data["riegl.pointcloud_info"]
        jj = json.loads(pcinfostr)
        if "field_of_application" in jj:
            if jj["field_of_application"] == "KLS":
                projType = "KLS"
            else:
                projType = jj["field_of_application"]
        else:
            pass
        
        # if isolated points have been classified and points have been deleted theres a chance noise has been removed
        # we don't know for sure if the point cloud is clean from all noise or not but this is the workflow that would result in a cleaned point cloud 
        if isoPoint >= 1 & delete >= 1:
            noiseRemove += 1

        for points in rdbopen.select("(riegl.id == 10)" ): 
            rt = points.riegl_waveform_available[0]
            break
        # 1 = waveforms available, 0 = no waveforms found
        if rt == 1:
            waveforms = 1
        else:
            waveforms = 0

    if build > 0:
        classli += 3,4,5,6
    if ground >0:
        classli += 1,2

    classli.sort()
    
    toc = time.perf_counter()
    Timetaken = toc-tic
    
    possibleWarnings =""

    response = "{0}; {1}; {2}; {3}; {4}; {5}; {6}; {7}; {8}; {9}; {10}; {11}".format(datacreated, lastmod, str(pointsclassified), str(ground), str(build), 
                                                                           str(colour), str(noiseRemove), str(waveforms), classli, Timetaken, projType, possibleWarnings)

    sys.stdout.write(response)
        


if __name__ == "__main__":
        SearchRDBXTransactions(sys.argv)
        #SearchRDBXTransactions(["D:\\Riegl Projects\\Kinemantic\\ALS\\P2521_211020_OE-KRI_VQ-580II_H2225802-RG-Realtime\\06_RIEGL_PROC\\07_RDB\\Record010_Sinken_450m 800m 600kHz\\211020_144658_Scanner_1\\211020_144658_Scanner_1.rdbx"])




