<?php
/**
 * @copyright Gmed srl
 * @author Riccardo Sciarrone <riccardos@gmed.it>
 *
 * ARM
 * Gestore di chiamate DICOM a server OrtHanc
 */



/*
  STATUS dello STUDIO
  0 =>  NUOVO
  1 =>  MODIFICATO (arrivata modifica ad uno esistente)

  2 =>  DA ELABORARE
  - versione manuale => Accession Number confermato dall'utente
  - versione automatica => viene messo in questo stato automaticamente alla ricezione

  5 =>  ELABORATO (l'AccessionNumber è stato inserito in tutte le Instances)
  lo studio è pronto per essere spedito

  7 =>  SPEDITO
  lo studio può ancore essere rispedito a mano

  9 =>  RIMOSSO
  lo studio NON è più su ortHanc QUINDI non può più essere rispedito
 */


/**
 * 
 * funzione che ritorna un JSON con tutto lo studio/serie/instances
 * 
 * @param string    $orthanc_id
 * @return array
 */
function retrieve_single_study( $orthanc_id ) {

    WriteLog( "RICERCA dello studio $orthanc_id", orthanc_call_logfile, "INFO" );
    $cmd = orthanc_url . '/studies/' . $orthanc_id . '?expand';
    
    //echoo("\ncomando: $cmd\n");
    $study = call_orthanc( $cmd, "STUDIO" );

    
    if( isset($study["error"]) ){
        // non è tornato nullo
        //echoo("STUDIO $orthanc_id ERRORE " . $study["error"] . " - " .$study["descr"] . "\n\n");
        WriteLog("STUDIO $orthanc_id ERRORE " . $study["error"] . " - " .$study["descr"], orthanc_call_logfile, "WARNING");
        return $study;
    }
    
    
    $accession_numbers = isset($study["MainDicomTags"]["AccessionNumber"]) ? 
                                Array( trim($study["MainDicomTags"]["AccessionNumber"]) ) 
                            :   Array();


    $study_series = $study["Series"];
    $study["Series"] = Array();
    foreach ($study_series as $serie_id) {
        $serie = call_orthanc(orthanc_url . '/series/' . $serie_id . '?expand', "SERIE");
        $study["Series"][$serie_id] = $serie;
        $serie_instances = $serie["Instances"];
        $study["Series"][$serie_id]["Instances"] = Array();
        
        
        foreach ( $serie_instances as $instance_id ) {
            //echo "\t\ttrovata Istance: $instance_id\n";
            $instance = call_orthanc(orthanc_url . '/instances/' . $instance_id . '?expand', "INSTANCE");
            $dcm_tags = explode(",", dcm_tags);

            foreach ( $dcm_tags as $dcm_tag ) {
                $i_cmd = orthanc_url . '/instances/' . $instance_id . '/content/' . $dcm_tag;
                //echoo("\t\t$i_cmd \n");
                $instance[$dcm_tag] = call_orthanc(orthanc_url . '/instances/' . $instance_id . '/content/' . $dcm_tag, "INSTANCE_" . $dcm_tag, TRUE);

                if (isset($instance["0008-0050"]) && isset($instance["0008-0050"]) != '') {
                    $ac = trim($instance["0008-0050"]);
                    $instance["0008-0050"] = $ac;
                    // c'è un accession number su questa ISTANZA
                    if ( !in_array($ac, $accession_numbers) ) {
                        array_push($accession_numbers, $ac);
                    }
                }
            }
            $study["Series"][$serie_id]["Instances"][$instance_id] = $instance;
            $study["Instances"][$instance_id] = $instance;
        }
        $study["calculated_acc_numb"] = $accession_numbers;
    }


    return $study;
}


/**
 * funzione che chiama un CURL GET con basic authentication
 * 
 * @param string    $url        ip dei orthanc
 * @param string    $type       tipo di operazione nel LOG
 * @param bool      $single_value   torna un singolo valore
 * @param string    $custom_request GET/POST
 * @param text/json $post_fields    oggetto con i parametri POST
 * @param bool      $check_error_in_resp controllare eventuali errori
 * @return string[]
 */
function call_orthanc($url, $type = "GENERIC", $single_value = FALSE, $custom_request = 'GET', $post_fields = "{}", $check_error_in_resp = TRUE) {

    WriteLog("call_orthanc $url ", orthanc_call_logfile, "INFO");
    $curl = curl_init();

    
    $curl_prm = array(
                CURLOPT_URL => $url,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_ENCODING => '',
                CURLOPT_MAXREDIRS => 10,
                CURLOPT_TIMEOUT => 0,
                CURLOPT_FOLLOWLOCATION => true,
                CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                CURLOPT_CUSTOMREQUEST => $custom_request,
                CURLOPT_POSTFIELDS => $post_fields,
                CURLOPT_HTTPHEADER => array(
                    'Authorization: Basic ' . base64_encode(orthanc_username . ":" . orthanc_password),
                    'Content-Type: application/json'
                ),
            );

    $curl = curl_init();
    curl_setopt_array(
            $curl,
            $curl_prm
    );
    
    

    //if( $post_fields != null ){
    //    // aggiungo i campi POST
    //    array_push( curl_setopt_array[1], Array( 'CURLOPT_POSTFIELDS' => $post_fields) );
    //}
    
    
    $response = curl_exec($curl);


    if (curl_errno( $curl )) {
        return array(
            'error' => 800,
            'descr' => curl_error( $curl )
        );
    }
    
    
    if (!$single_value && !$response) {
        WriteLog("$type: NESSUN RISULTATO  $url", orthanc_call_logfile, "ERROR");
        return array(
            'error' => 900,
            'descr' => "NESSUN RISULTATO ALLA CHIAMATA"
        );
    }

    if ( $check_error_in_resp && strpos($response, "Error") !== false ) {
        WriteLog("$type: ERRORE  $url  $response", orthanc_call_logfile, "ERROR");
        return array(
            'error' => 901,
            'descr' => $response
        );
    }
    
    
    WriteLog("risposta $response ", orthanc_call_logfile, "INFO");
        
    if ($single_value) {
        // mi aspetto un singolo valore e NON un Json
        $data = $response;
    } 
    else {
        $data = json_decode($response, true);
    }
    curl_close($curl);
    usleep(orthanc_timeout);
 
    return $data;
}






/**
 * prende la data DICOM  YYYYMMDD e la converte in YYYY-MM-DD
 * 
 * @param string $fld
 * @return string
 */
function dcm_date( $fld ) {
    if ($fld == '') {
        return "null";
    }
    $fld = "'" . substr($fld, 0, 4) . "-" . substr($fld, 4, 2) . "-" . substr($fld, 6, 2) . "'";

    $to_check = substr($fld, 1, 10) . " 00:00:01";
    echo "dcm_date: controllo questa data: $to_check  => " . (strtotime($to_check ) ? "OK" : "KO") . "<br/>";
    if( strtotime($to_check) ){
        // è una data valida
        return $fld;
    }
    return "'" . date("Y-m-d H:i:s") . "'";
}



/**
 * prende la data DICOM  YYYYMMDD e il TIME HHiiss  e la converte in YYYY-MM-DD HH:ii:ss
 * 
 * @param string $dt
 * @param string $tm
 * @return string 
 */
function dcm_time( $dt, $tm ) {

    $pos = strpos($tm, '.');
    if ($pos !== false) {
        $tm = substr( $tm, 0, $pos );
    }
    echo "dcm_time: controllo questa data: $dt $tm => " . (strtotime($dt . " " . $tm) ? "OK" : "KO") . "<br/>";

    if ( $dt == '' || !strtotime($dt . " " . $tm) ) {
        return "null";
    }
    $fld = "'" . substr($dt, 0, 4) . "-" . substr($dt, 4, 2) . "-" . substr($dt, 6, 2) . " ";
    $fld .= substr($tm, 0, 2) . ":" . substr($tm, 2, 2) . ":" . substr($tm, 4, 2) . "'";
    return $fld;
}



/*
  $curl = curl_init();

  curl_setopt_array($curl, array(
  CURLOPT_URL => orthanc_url . '/studies?expand',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'GET',
  CURLOPT_POSTFIELDS =>'{
  "Level" : "Instance",
  "Query" : {
  "StudyDate" : "20110322-",
  "PatientID" : "*"
  }
  }',
  CURLOPT_HTTPHEADER => array(
  'Authorization: Basic '  . base64_encode(orthanc_username . ":" . orthanc_password),
  'Content-Type: application/json'
  ),
  ));

  $response = curl_exec($curl);

  if(!$response){
  die("Nessuna connessione");
  }
  curl_close($curl);


  //echo $response;

  // metto la risposta JSON in un array PHP
  $studies = json_decode($response, true);
 */


/**
 * visualizza a video (web o cmd) il valore di una variabile
 * 
 * @param string/array $stringa
 * @param bool $pre     si TRUE farà il DUMP
 */
function echoo( $stringa, $pre = false, $nl = TRUE ) {

    if ($pre) {
        if (exec_as == "web") {
            echo "<pre>";
        }
        print_r($stringa);
        if (exec_as == "web") {
            echo "</pre>";
        }
    } 
    else {
        if (exec_as == "web") {
            $stringa = str_replace("\n", "<br/>", $stringa);
            $stringa = str_replace("\t", "&nbsp&nbsp&nbsp&nbsp&nbsp", $stringa);
        }
        if (exec_as == "cmd") {
            $stringa = str_replace("<br/>", "\n", $stringa);
            $stringa = str_replace("<br>", "\n", $stringa);
            $stringa = str_replace("<hr/>", "\n----------------------------------------\n", $stringa);
            $stringa = str_replace("<hr>", "\n----------------------------------------\n", $stringa);
        }
        echo $stringa;
    }
    
    if( $nl ){
        if (exec_as == "web") {
            echo "<br/>";
        }
        if (exec_as == "cmd") {
            echo "\n>";
        }        
    }

    flush();
    @ob_flush();
}



/**
 * controlla se esiste il pid della procedura
 * se esiste si ferma
 * altrimenti lo crea
 * 
 * @param string $name
 * @param bool $create
 * @return boolean
 */
function check_pid($name, $create = TRUE){
    
    $pid_name = pids_dir . $name . ".pid";
    if ( file_exists($pid_name) ){
        die("PROGRAMMA  $pid_name  GIA' IN ESECUZIONE");
    }
    
    if ( $create ){
        $fh = @fopen($pid_name, 'w') or die("Can't create file $pid_name");
        file_put_contents($pid_name, Date("Y-m-r H:i:s") );
        if( exec_as == "web" ){
            file_put_contents( $pid_name, print_r($_SERVER, true), FILE_APPEND );
        }
    }
    return false;
}


/**
 * cancella un file PID
 * 
 * @param string $name
 */
function kill_pid( $name ){
    
    $pid_name = pids_dir . $name . ".pid";
    if ( file_exists($pid_name) ){
        unlink( $pid_name );
    }
 
}


/**
 * altra chiamata della cancellasione di un PID
 * 
 * @param string $string
 * @param string $pid_name
 */
function die_proc( $string, $pid_name ){
    kill_pid( $pid_name );
    die( $string );
}