<?php

namespace FR\V1_0\Models;

class RemoteHubModel implements \FR\Interfaces\RemoteHubModelInterface
{
    private static $columns = [
        'hostkey',
        'ui_name',
        'api_url',
        'role',
        'target_state',
        'transport'
    ];
    private $tableName = 'remote_hubs';
    /**
     * @var \PDO
     */
    private $cfPdo;
    /**
     * @var \PDO
     */
    private $cfdbPdo;

    public function __construct(\PDO $cfPdo, \PDO $cfdbPdo)
    {
        $this->cfPdo = $cfPdo;
        $this->cfdbPdo = $cfdbPdo;
    }

    public function get($id)
    {
        $sql = sprintf('SELECT * FROM %s WHERE id = ?', $this->tableName);
        $statement = $this->cfPdo->prepare($sql);
        $statement->execute([$id]);
        $hub = $statement->fetch(\PDO::FETCH_ASSOC);

        if (!$hub) {
            throw new \ResponseException('Remote hub not found', \Response::NOTFOUND);
        }

        return $hub;
    }

    public function findByName($name)
    {
        $sql = sprintf('SELECT * FROM %s WHERE ui_name = :name', $this->tableName);
        $statement = $this->cfPdo->prepare($sql);
        $statement->execute(['name' => $name]);
        $hub = $statement->fetch(\PDO::FETCH_ASSOC);
        return $hub;
    }

    public function getList()
    {
        $sql = sprintf('SELECT * FROM %s ORDER BY id', $this->tableName);
        $hubs = $this->cfPdo->query($sql)->fetchAll(\PDO::FETCH_ASSOC);
        return $hubs;
    }

    public function create(array $data)
    {
        foreach ($data as $column => $value) {
            if (!in_array($column, self::$columns)) {
                unset($data[$column]);
            }
        }

        $sql = sprintf(
            'INSERT INTO  %s  
                       (hostkey, ui_name, role, target_state,  transport, api_url) 
                       VALUES (:hostkey, :ui_name, :role, :target_state, :transport, :api_url)',
            $this->tableName
        );
        $result = $this->cfPdo->prepare($sql);
        $result->execute($data);

        if ((int)$result->errorCode() > 0) {
            syslog(LOG_ERR, __CLASS__ . '::' . __METHOD__ . ': database error while inserting - ' . implode(
                ' - ',
                $result->errorInfo()
            ));
            throw new \Exception('Database error, please see error log.');
        }
    }

    public function update($id, array $data)
    {
        $sql = sprintf('UPDATE  %s SET ', $this->tableName);
        $set = [];
        foreach ($data as $column => $value) {
            if (in_array($column, self::$columns)) {
                $set[] = "$column = :$column";
            } else {
                unset($data[$column]);
            }
        }
        $sql .= implode(', ', $set);
        $sql .= ' WHERE id = ' .$id;
        $result = $this->cfPdo->prepare($sql);
        $result->execute($data);

        if ((int)$result->errorCode() > 0) {
            syslog(LOG_ERR, __CLASS__ . '::' . __METHOD__ . ': database error while updating - ' . implode(' - ', $result->errorInfo()));
            throw new \Exception('Database error, please see error log.');
        }
    }

    public function delete($id)
    {
        $stmtFeederExistsSQL = $this->cfdbPdo->prepare('SELECT * FROM __hubs WHERE hub_id = ?');
        $stmtFeederExistsSQL->execute([$id]);
        if ($stmtFeederExistsSQL->fetch(\PDO::FETCH_ASSOC)) {
            $sql = sprintf("SELECT remove_feeder_data(%d)", intval($id));
            $this->cfdbPdo->prepare($sql)->execute();
        }

        $sql = sprintf('DELETE FROM %s WHERE id = ?', $this->tableName);
        return $this->cfPdo->prepare($sql)->execute([$id]);
    }

}
