<?php
/*
* getNewick.php
* http://tasuke.dna.affrc.go.jp/
*
* Author: Norio Tabei
*
* Copyright (c) 2020 National Institute of Agrobiological Sciences
*
*/

require '../conf/config.php';
require './common.php';
require_once "./PHPPhylogeneticTrees/autoload.php";

use PHPPhylogeneticTrees\NJTree;
//////////////////////////////////  Connecting with DB
if( !$conn = new mysqli($host, $user, $pswd, $db)) {
    error_log("Connection failed.\n");
    exit;
}

(isset($_POST['prm_Lists']) && !empty($_POST['prm_Lists'])) ? $prm_Lists=$_POST['prm_Lists'] : returnError("Error");
// $prm_Lists = "[\"SAMD00045871\",\"SAMD00045886\",\"SAMD00045903\"]";	//TODO error dataset
//$prm_Lists = "[\"SAMD00045871\",\"SAMD00045886\",\"SAMD00045903\",\"SAMD00045958\"]";

$id2DbMap = getId2DbMap($conn);

$taxa_dmatrix = readDistanceMatrixFile($distanceMatrixPath);
$taxa = $taxa_dmatrix[0];
$d_mat = $taxa_dmatrix[1];
if(!empty($prm_Lists)) {
	$res = rebuildMatrix($taxa, $d_mat, $prm_Lists);
	$taxa = $res[0];
	$d_mat = $res[1];
}
//var_dump($taxa);
//var_dump($d_mat);

$taxaDb = array();
foreach($taxa as $id) {
	$taxaDb[] = $id2DbMap[$id];
}

$nj = new NJTree($d_mat);
//error_log("Test2:". json_encode($nj->getLabels()));
$newick = $nj->getNewick($taxaDb);

echo $newick;

function getId2DbMap($conn) {
	$map = array();
	$stmt = $conn->stmt_init();
	$query = "SELECT accession_id, accession_db FROM sys_accession";
	$stmt->prepare($query);
	$stmt->execute();
	$stmt->store_result();
	$stmt->bind_result($id, $db);
	while ($stmt->fetch()) {
		$map[$id] = $db;
	}
	return $map;
}
function readDistanceMatrixFile($file) {
	$taxa = [];
	$dmatrix = [];
	$IN = fopen($file, "r");
	$tgtIndex = 0;
	if($IN){
		while($line = fgets($IN)) {
			$line = rtrim($line);
			if(!preg_match("/\S/", $line) || preg_match("/^[\s\d]+$/", $line)) continue;

			$onerowArrayPre = preg_split("/\s+/", $line);
			$onerowArray = [];
			$acc = array_shift($onerowArrayPre);
			$taxa[] = $acc;
			$arrayLen = count($onerowArrayPre);
			for($i=0; $i<$tgtIndex && $i<$arrayLen; $i++) {
//error_log("Test:". $tgtIndex. ",". $i. "(". $acc. ")=". $onerowArrayPre[$i]);
				$onerowArray[$i] = (float) $onerowArrayPre[$i];
			}
			$dmatrix[] = $onerowArray;
			$tgtIndex++;
		}
	}
	return [$taxa, $dmatrix];
}
function rebuildMatrix($taxa, $d_mat, $prm_Lists) {
	if(empty($prm_Lists)) return array($taxa, $d_mat);

	$taxaLen = count($taxa);
	$taxaId2Index = array();
	for($i=0; $i<$taxaLen; $i++) {
		$taxaId2Index[$taxa[$i]] = $i;
	}

	// Remove Acc that does not exist in distance matrix
	$preDestTaxa = json_decode($prm_Lists);
	$preDestTaxaLen = count($preDestTaxa);
	$destTaxa = [];
	for($i=0; $i<$preDestTaxaLen; $i++) {
		if(array_key_exists($preDestTaxa[$i], $taxaId2Index)) $destTaxa[] = $preDestTaxa[$i];
	}

	$destTaxaLen = count($destTaxa);
	$destDmat = array();
	for($i=0; $i<$destTaxaLen; $i++) {
		$taxaRowIndex = $taxaId2Index[$destTaxa[$i]];
		$destDmat[$i] = array();
		for($j=0; $j<$i; $j++) {
			$taxaColIndex = $taxaId2Index[$destTaxa[$j]];
			$d;
			if($taxaRowIndex < $taxaColIndex) {
				$d = $d_mat[$taxaColIndex][$taxaRowIndex];
			} else {
				$d = $d_mat[$taxaRowIndex][$taxaColIndex];
			} 
//echo "$i => $taxaRowIndex, $j => $taxaColIndex, = $d\n";
			$destDmat[$i][$j] = $d;
		}
		
	}	
	return array($destTaxa, $destDmat);
}
function returnError($str){
    echo $str;
}
?>
