<?php


/**
 * @uri /host-groups/personal/ 0
 */
class PersonalHostGroups extends CfProtectedResource
{
    private $personalHostGroupsModel;

    public function __construct($parameters)
    {
        parent::__construct($parameters);

        $this->personalHostGroupsModel = new PersonalHostGroupsModel($this->username);
    }

    /**
     * @rbacName Get personal host groups
     * @rbacGroup Personal Host Groups API
     * @rbacAlias host-groups-personal.get
     * @rbacAllowedByDefault
     */
    public function get($request)
    {
        $response = new Response($request);
        $response->code = Response::OK;
        $args = $_GET;

        if (isset($args['sortColumn']) && !in_array($args['sortColumn'], PersonalHostGroupEntity::sortableColumns())) {
            throw new InvalidArgumentException("sortColumn `{$args['sortColumn']}` is not allowed.");
        }
        $args['username'] = $this->username;
        $response->body = json_encode($this->personalHostGroupsModel->list($args, ['owner = :owner'], ['owner' => $this->username]));
        return $response;
    }

    /**
     * @rbacName Create personal host groups
     * @rbacGroup Personal Host Groups API
     * @rbacAlias host-groups-personal.post
     * @rbacAllowedByDefault
     */
    public function post($request)
    {
        $response = new Response($request);
        $response->code = Response::CREATED;

        $requestData = Utils::getValidJsonData($request->data);

        $requestData->owner = $this->username;
        $personalGroup = new PersonalHostGroupEntity(...(array)$requestData);

        if ($personalGroup->validate()) {
            $id = $this->personalHostGroupsModel->create($personalGroup);
            $response->body = json_encode(['id' => $id]);
        }

        return $response;
    }
}


/**
 * @uri /host-groups/personal/:id/
 */
class PersonalHostGroup extends CfProtectedResource
{
    private $personalHostGroupsModel;

    public function __construct($parameters)
    {
        parent::__construct($parameters);

        $this->personalHostGroupsModel = new PersonalHostGroupsModel($this->username);
    }

    /**
     * @rbacName Get personal host groups
     * @rbacGroup Personal Host Groups API
     * @rbacAlias host-groups-personal.get
     * @rbacAllowedByDefault
     */
    public function get($request, $id)
    {
        $response = new Response($request);
        $response->code = Response::OK;
        if (!$group = $this->personalHostGroupsModel->get(intval($id))) {
            $response->code = Response::NOTFOUND;
            return $response;
        }
        $response->body = json_encode($group);
        return $response;
    }


    /**
     * @rbacName Update personal host groups
     * @rbacGroup Personal Host Groups API
     * @rbacAlias host-groups-personal.patch
     * @rbacDescription  Update filter and name, excluding group data
     * @rbacAllowedByDefault
     */
    public function patch($request, $id)
    {
        $id = intval($id);
        $response = new Response($request);
        $response->code = Response::OK;

        if (!$this->personalHostGroupsModel->get($id)) {
            $response->code = Response::NOTFOUND;
            return $response;
        }

        $requestData = Utils::getValidJsonData($request->data);

        $groupEntity = new PersonalHostGroupEntity();

        if (isset($requestData->name) && !empty($requestData->name)) {
            Validator::name($requestData->name);
            $groupEntity->setName($requestData->name);
        }

        if (isset($requestData->description) && !empty($requestData->description)) {
            $groupEntity->setDescription($requestData->description);
        }

        if (isset($requestData->filter) && !empty($requestData->filter)) {
            $groupEntity->setFilter($requestData->filter);
        }

        $this->personalHostGroupsModel->update($id, $groupEntity);

        $response->body = json_encode(
            $this->personalHostGroupsModel->get($id)
        );

        return $response;
    }

    /**
     * @rbacName Delete personal host groups
     * @rbacGroup Personal Host Groups API
     * @rbacAlias host-groups-personal.delete
     * @rbacAllowedByDefault
     */
    public function delete($request, $id)
    {
        $response = new Response($request);
        $response->code = Response::NOCONTENT;
        if (!$this->personalHostGroupsModel->get(intval($id))) {
            $response->code = Response::NOTFOUND;
            return $response;
        }
        $this->personalHostGroupsModel->delete(intval($id));
        return $response;
    }
}

/**
 * @uri /host-groups/personal/:id/share
 */
class SharePersonalHostGroup extends CfProtectedResource
{
    /**
     * @rbacAlias host-groups-shared.post
     */
    public function post($request, $id)
    {
        $id = intval($id);
        $response = new Response($request);
        $response->code = Response::OK;

        if (!isActionAllowed($this->username, 'host-groups-personal.delete')) {
            throw new AccessDenyException("Action is not allowed. Permission to delete personal group is missing.");
        }

        $personalHostGroupsModel = new PersonalHostGroupsModel($this->username);
        $sharedHostGroupsModel = new SharedHostGroupsModel($this->username);

        if (!($group = $personalHostGroupsModel->get($id))) {
            $response->code = Response::NOTFOUND;
            return $response;
        }

        $personalGroupEntity = new PersonalHostGroupEntity(...$group);
        $sharedHostGroupsEntity = new SharedHostGroupEntity(...$personalGroupEntity->toArray());
        $sharedHostGroupsEntity->setCreator($personalGroupEntity->getOwner());

        $newID = $personalHostGroupsModel->makeShared($id, $sharedHostGroupsEntity, $sharedHostGroupsModel);
        $response->body = json_encode(['id' => $newID]);
        return $response;
    }
}


/**
 * @uri /host-groups/personal/:id/favorite
 */
class PersonalHostGroupFavorite extends CfProtectedResource
{
    private $personalHostGroupsModel;
    private $favoriteHostGroupsModel;

    public function __construct($parameters)
    {
        parent::__construct($parameters);

        $this->personalHostGroupsModel = new PersonalHostGroupsModel($this->username);
        $this->favoriteHostGroupsModel = new FavoriteHostGroupsModel();
    }


    /**
     * @rbacName Add group to favorite
     * @rbacGroup Personal Host Groups API
     * @rbacAlias host-groups-personal-favorite.post
     * @rbacAllowedByDefault
     */
    public function post($request, $id)
    {
        $id = intval($id);
        $response = new Response($request);
        $response->code = Response::OK;

        if (!$this->personalHostGroupsModel->get($id)) {
            $response->code = Response::NOTFOUND;
            return $response;
        }

        $this->favoriteHostGroupsModel->add($id, $this->username);

        return $response;
    }

    /**
     * @rbacName Remove group from favorite
     * @rbacGroup Personal Host Groups API
     * @rbacAlias host-groups-personal-favorite.delete
     * @rbacAllowedByDefault
     */
    public function delete($request, $id)
    {
        $response = new Response($request);
        $response->code = Response::NOCONTENT;

        if (!$this->personalHostGroupsModel->get(intval($id))) {
            $response->code = Response::NOTFOUND;
            return $response;
        }

        $this->favoriteHostGroupsModel->remove($id, $this->username);

        return $response;
    }
}
