<?php class autoprocessingresult extends baseobject {

    protected static array $fields=array(
        'name'=>validator::REQUIRED,
		'starrating'=>validator::INTEGER,
        'datasetid'=>validator::REQUIRED,
        'pipelinename'=>validator::REQUIRED,
        'scalingstatisticstype'=>validator::REQUIRED,
        'succeeded'=>validator::REQUIRED,
        'isanomalous'=>validator::BOOLEAN,
        'spacegroup'=>validator::ANY,
        'completeness'=>validator::FLOAT,
        'bestresolution'=>validator::FLOAT,
        'rmerge'=>validator::FLOAT,
        'rpim'=>validator::FLOAT,
        'cchalf'=>validator::FLOAT,
        'ioversigma'=>validator::FLOAT,
        'remoteobject'=>validator::ANY
    );

    protected static array $helpTexts=array(

    );

    public static string $defaultSortOrder='autoprocessingresult.name';

    public static function create(array $request=[]): array {
		shipment::setShipperAdmin();
        if(empty($request['remoteid'])){
            throw new BadRequestException('No remoteid supplied');
        }
        if(empty($request['scalingstatisticstype'])){
            //SynchWeb doesn't use this. ISPyB REST sends parameters like rmerge as a comma-separated
            //triplet with values for overall, innerShell and outerShell, but in a variable order(!),
            //which is specified in this parameter.
            $request['scalingstatisticstype']='n/a';
        }
        if(empty($request['parameters'])){
            $request['parameters']=array();
        }
        $parameters=$request['parameters'];
        if(!is_array($parameters)){
            $parameters=json_decode($request['parameters'], true);
        }
        $projectId=$request['projectid'];
        $request["succeeded"]=true;
        $request['name']="ds".$request['datasetid'].'_'.$request['pipelinename'].'_remoteid_'.$request['remoteid'];
        if(isset($parameters["anomalousPhasing"]) && 1*$parameters["anomalousPhasing"]){
            $request['name'].='_anomalous';
            $request['isanomalous']=true;
        } else {
            $request['isanomalous']=false;
        }
        $existing=static::getByName($request['name']);
        if($existing){
            $autoProcessingResultId=$existing['id'];
            $ret=static::update($autoProcessingResultId,$request);
            $ret=$ret['updated'];
        } else {
            $ret=parent::create($request);
            $ret=$ret['created'];
            $autoProcessingResultId=$ret['id'];
        }
        $ret['parameters']=[];
        foreach ($parameters as $key=>$value) {
            $parameterName=$request['name'].'_'.$key;
            $parameter=autoprocessingresultparameter::getByName($parameterName);
            if($parameter){
                autoprocessingresultparameter::update($parameter['id'],array(
                    'parametervalue' => $value
                ));
            } else {
                autoprocessingresultparameter::create(array(
                    'name'=>$parameterName,
                    'projectid' => $projectId,
                    'autoprocessingresultid' => $autoProcessingResultId,
                    'parametername' => $key,
                    'parametervalue' => $value
                ));
            }
            $ret['parameters'][$key]=$value;
        }
        dataset::setBestResolutionFromAutoProcessingResults($request['datasetid']);
		shipment::revertShipperAdmin();
        return array('created'=>$ret);
    }

    /**
     * @return bool
     * @throws NotFoundException
     */
    public static function canCreate(): bool {
        return session::isShipper() || session::isAdmin();
    }

	/**
	 * @param int $id
	 * @return bool
	 * @throws NotFoundException
	 */
    public static function canUpdate(int $id): bool {
        return session::isShipper() || session::isAdmin();
    }

	/**
	 * @param int $id
	 * @param array $request
	 * @return array
	 * @throws BadRequestException
	 * @throws ForbiddenException
	 * @throws NotFoundException
	 * @throws ServerException
	 */
	public static function update(int $id, array $request=[]): array {
		shipment::setShipperAdmin();
		$updated=parent::update($id, $request);
		if(isset($request['starrating'])){
			$datasetId=$updated['updated']['datasetid'];
			dataset::setBestResolutionFromAutoProcessingResults($datasetId);
		}
		shipment::revertShipperAdmin();
		return $updated;
	}

	/**
	 * @param int $id
	 * @param array $request
	 * @return array|null
	 * @throws BadRequestException
	 * @throws ServerException
	 */
	public static function getautoprocessingresultparameters(int $id, array $request=[]): ?array {
        return autoprocessingresultparameter::getByProperty('autoprocessingresultid', $id, $request);
    }

}