<?php class construct extends protein { //Extend protein, which extends baseobject - same restrictions on canCreate
	
	protected static array $fields=array(
			'name'=>validator::REQUIRED,
			'description'=>validator::REQUIRED,
			'proteinid'=>array(validator::REQUIRED, validator::INTEGER),
	);

	protected static array $helpTexts=array(
			'name'=>'A unique name for this construct',
			'description'=>'Short description of this construct',
			'proteinid'=>'The database ID of the parent protein',
	);
	
	
	protected static string $adminSelect='SELECT SQL_CALC_FOUND_ROWS construct.*, project.name AS projectname, project.isarchived AS isarchived, 
			protein.name AS proteinname, protein.proteinacronym as proteinacronym
			FROM construct, protein, project WHERE project.id=construct.projectid AND protein.id=construct.proteinid';
	protected static string $normalSelect='SELECT SQL_CALC_FOUND_ROWS construct.*, project.name AS projectname, project.isarchived AS isarchived, 
			protein.name AS proteinname, protein.proteinacronym as proteinacronym
			FROM construct, protein, project WHERE project.id=construct.projectid AND protein.id=construct.proteinid';
	
	
	public static function create(array $request=[]): array {
		if(!isset($request['proteinid'])){ throw new BadRequestException('No parent protein specified'); }
		$protein=protein::getById($request['proteinid']);
		if(!$protein){
		    throw new NotFoundException('Protein does not exist, or you do not have permission to see it');
        }
		if(!session::isAdmin()){
			$project=project::getById($protein['projectid']);
			if(!$project){
				throw new NotFoundException('Project does not exist, or you do not have permission to see it');
			}
			if($project['owner']!=session::getUserId()){
				throw new ForbiddenException('You must own the project to create proteins and constructs in it');
			}
		}
		$request['projectid']=$protein['projectid'];
		return baseobject::createByClassName($request,'construct');
	}

	/**
	 * Gets all constructs (visible to the user) with the specified name. A custom implementation is needed here because,
	 * unlike most types, the name of a construct is not guaranteed to be globally unique. It is unique only within a
	 * given protein; several proteins even in the same project might have a "Full length" construct, for example.
	 * @param string $name The name of the construct
	 * @param array $request The request parameters
	 * @return array|null
	 * @throws BadRequestException
	 * @throws ServerException
	 */
	public static function getByName(string $name, array $request=[]): ?array {
		return self::getByProperty('name', $name, $request);
	}

	/**
	 * Gets the sequences for this construct.
	 * @param int $id The construct ID
	 * @param array $request The request parameters, e.g., pagination
	 * @return array|null
	 * @throws BadRequestException
	 * @throws ServerException
	 */
	public static function getsequences(int $id, array $request=[]): ?array {
		return sequence::getByProperty('constructid',$id,$request);
	}
}