<?php

    require '../conf/config.php';
    require './common.php';
    require './commonDB.php';
    require './lockfile.php';
    require './getServerInfo.php';

    // Ajax以外からのアクセスを遮断
    $request = isset($_SERVER['HTTP_X_REQUESTED_WITH']) ? strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) : '';
    if($request !== 'xmlhttprequest'){_stopError("||Invalid connecton.");}
    header("Content-Type: application/json; charset=UTF-8");

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

    // Parameters
    (isset($_POST['prm_phy_chr']) && !empty($_POST['prm_phy_chr'])) ? $prm_chr=$_POST['prm_phy_chr']:_stopError("||Invalid value:Chr");
    (isset($_POST['prm_phy_s']) && !empty($_POST['prm_phy_s'])) ? $prm_s=$_POST['prm_phy_s']:_stopError("||Invalid value:Start");
    (isset($_POST['prm_phy_e']) && !empty($_POST['prm_phy_e'])) ? $prm_e=$_POST['prm_phy_e']:_stopError("||Invalid value:End");
    (isset($_POST['qry_list'])) ? $qry_list=$_POST['qry_list']:_stopError("||Invalid value:Query");
    (isset($_POST['prm_phy_qual'])) ? $prm_qual=$_POST['prm_phy_qual']:_stopError("||Invalid value:Qual");
    (isset($_POST['prm_phy_dp'])) ? $prm_dp=$_POST['prm_phy_dp']:_stopError("||Invalid value:Depth");
    (isset($_POST['prm_phy_list']) && !empty($_POST['prm_phy_list'])) ? $prm_list=$_POST['prm_phy_list'] : _stopError("||Invalid value:List");
    (isset($_POST['prm_phy_cri'])) ? $prm_cri=$_POST['prm_phy_cri'] : _stopError("||Invalid value:Select");
    (isset($_POST['prm_phy_gene'])) ? $prm_gene=$_POST['prm_phy_gene'] : _stopError("||Invalid value:Gene");
    (isset($_POST['prm_phy_name'])) ? $prm_name=$_POST['prm_phy_name'] : _stopError("||Invalid value:Name");
//    (isset($_POST['prm_numthread'])) ? $prm_numthread=$_POST['prm_numthread'] : _stopError("||Invalid value:Thread");
    (isset($_POST['prm_phy_objid'])) ? $prm_obj_id=$_POST['prm_phy_objid'] : _stopError("||Invalid value:Gene ID");
    $prm_phy_grp = "variety";	// Dummy, Currently, the sample name is always returned as "d *".
//    (isset($_POST['prm_phy_grp'])) ? $prm_phy_grp=$_POST['prm_phy_grp'] : _stopError("||Invalid value:Group");
    (isset($_POST['sid']) && !empty($_POST['sid'])) ? $sid=$_POST['sid'] : _stopError("||Invalid value:Session");
    (isset($_POST['prm_phy_method']) && !empty($_POST['prm_phy_method'])) ? $prm_phy_method = $_POST['prm_phy_method'] : $prm_phy_method = "dna";

    $variant_types = "sid";
    if(isset($_POST['prm_phy_method_vtypes']) && !empty($_POST['prm_phy_method_vtypes'])) $variant_types = $_POST['prm_phy_method_vtypes'];
//error_log("Test:". $prm_phy_method. ",". $variant_types);
    if(preg_match("/[^sid]/i", $variant_types)) _stopError("||Invalid value:Variant type(s/i/d)");

    $dir = __DIR__;
    $list = explode(",",$prm_list);

    // Validating
    if(isset($_SERVER["HTTP_HOST"])){
      _pregMatch($prm_obj_id);
      _pregMatch($prm_name);
      if(!_validate_chrs($conn,$prm_chr)){_stopError("||Invalid value:Chr");}
      if(!_validate_num($prm_s)){_stopError("||Invalid value:Start");}
      if(!_validate_num($prm_e)){_stopError("||Invalid value:End");}
      $se_len = $prm_e - $prm_s + 1;
      if($prm_cri == 1 && $prm_gene == 1 && !empty($prm_obj_id)) {
        $reg_info = getCDSLength($conn, $prm_obj_id);
	$se_len = $reg_info['cds']['len'];
//        $se_len = getCDSLength($conn, $prm_obj_id, 'cds');
      }
      $maxLength = 20000;
      if ($se_len > $maxLength) {_stopError("||Invalid value:Length>". $maxLength);}
      if(!_validate_num($prm_qual)){_stopError("||Invalid value:Qual");}
      if(!_validate_num($prm_dp)){_stopError("||Invalid value:Depth");}
      if(!_validate_each_acc($list)){_stopError("||Invalid value:List");}
      _pregMatchQueryList($qry_list);
//      _pregMatch($qry_list);
      if($prm_cri != 1 and $prm_cri != 0){_stopError("||Invalid value:Select");}
      if($prm_gene != 1 and $prm_gene != 0){_stopError("||Invalid value:Gene");}
      if(_chk_cds($conn, $prm_obj_id) < 1 and $prm_gene == 1){_stopError("||Invalid CDS:This object does not have CDS region");}
      $prm_phy_grp = _validate_group($prm_phy_grp);
      if(!$prm_phy_grp){_stopError("||Invalid value:Group");}
//      if(!_validate_num($prm_numthread)){_stopError("||Invalid value:Thread");}
      _pregMatch($sid);
    }

    $return_array = getJobCount($tempdir, $sid);
    if ($return_array['snum'] > 1 || $return_array['sflg'] != "") {_stopError("||This program is very busy!!");}

    register_shutdown_function(function() use($tempdir, $sid) {
        // $tempdir, $sid is not the value when the function was executed, but the value when the function was defined.
        removeLockFile($tempdir, $sid);
    });
    makeLockFile($tempdir, $sid);
/*
    $snum = exec("ls $dir/../tmp | wc -l" );
    $sflg = exec("ls $dir/../tmp | grep $sid");
    if ($snum > 1 || $sflg != "") {_stopError("||This program is very busy!!");}
    $fpath = sprintf("%s/../tmp/%s.lock",$dir,$sid);
    touch($fpath);
*/
    try {
	$send_obj_id = $prm_obj_id;
	if(empty($send_obj_id)) $send_obj_id = "\"\"";

	$send_variant_types = $variant_types;
	if(empty($send_variant_types)) $send_variant_types = "\"\"";
	$cmd = "";
	if($prm_phy_method === "bin") {
		$cmd = "php bindist.php $prm_chr $prm_s $prm_e \"$qry_list\" $prm_qual $prm_dp \"$prm_list\" $prm_cri $prm_gene $prm_name $sid $prm_phy_grp $servername $headurl $send_obj_id $send_variant_types";
	} else { 
		$cmd = "php dnadist.php $prm_chr $prm_s $prm_e \"$qry_list\" $prm_qual $prm_dp \"$prm_list\" $prm_cri $prm_gene $prm_name $sid $prm_phy_grp $servername $headurl $send_obj_id";
	}
//error_log($cmd);
        // for Basic authentication.
        if(!empty($_SERVER['PHP_AUTH_USER'])) $cmd = "env PHP_AUTH_USER=". $_SERVER['PHP_AUTH_USER']. " PHP_AUTH_PW=". $_SERVER['PHP_AUTH_PW']. " ". $cmd;
        $out = array();
        exec($cmd,$out,$status);        // Background processing is currently on hold
        $out2 = implode("\n",$out);
        $return_array = array('result' => $out2, 'status'=>$status);
        echo json_encode($return_array);
    } catch ( Exception $ex ) {
      error_log("dnadist.php:error occur\n". $ex->getMessage(). "\n");
    }
//    removeLockFile($tempdir, $sid);
//    exec("rm $fpath");
    exit;

    function _stopError($str){
      $status = 0;
      $return_array = array('result' => $str, 'status'=>$status);
      echo json_encode($return_array);
      exit;
    }

    function _validate_chrs($conn, $prm_Chr){
      $flag = false;
      $query = "select seq from sys_chromosome where id=? limit 1";
      $stmt = $conn->stmt_init();
      $stmt->prepare($query);
      $stmt->bind_param("s", $prm_Chr);
      $stmt->execute();
      $stmt->store_result();
      $stmt->bind_result($row0);
      while ($stmt->fetch()) {
        $flag = true;
      }
      $stmt->free_result();
      $stmt->close();
      if($flag){
        return true;
      }else{
        return false;
      }
    }

    function _chk_cds($conn, $prm_obj_id){
      $cds = 0;
      $query = "select seq from sys_track where id=? and (type='CDS' or type='cds') limit 1";
      $stmt = $conn->stmt_init();
      $stmt->prepare($query);
      $stmt->bind_param("s", $prm_obj_id);
      $stmt->execute();
      $stmt->store_result();
      $stmt->bind_result($row0);
      while ($stmt->fetch()) {
        $cds++;
      }
      $stmt->free_result();
      $stmt->close();
      return $cds;
    }

    function _validate_each_acc($list){
      $num = count($list);
      $fflg = 0;
      for($a=0;$a<$num;$a++){
        if (preg_match("/^d\d+$/i", $list[$a])) {
            //pass
        }else{
		$fflg = $fflg + 1;
        }
      }
      if ($fflg > 0) {
		return false;
      } else {
		return true;
     }
    }

    function _validate_group($str){
      $keys = array(
        "variety" => "1",
        "sub_variety" => "1",
        "origin" => "1",
        "origin_2" => "1",
        "type" => "1",
        "other_1" => 1,
        "other_2" => 1
      );
      if($str == "subvariety" ){$str = "sub_variety";}
      if(array_key_exists($str, $keys)){
        return $str;
      }else{
        return false;
      }
    }
?>
