<?php

if (!defined('ABSPATH')) {
    exit;
}
class WC_API_Webhooks extends WC_API_Resource
{
    protected $base = '/webhooks';
    public function register_routes($routes)
    {
        $routes[$this->base] = array(array(array($this, 'get_webhooks'), WC_API_Server::READABLE), array(array($this, 'create_webhook'), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA));
        $routes[$this->base . '/count'] = array(array(array($this, 'get_webhooks_count'), WC_API_Server::READABLE));
        $routes[$this->base . '/(?P<id>\\d+)'] = array(array(array($this, 'get_webhook'), WC_API_Server::READABLE), array(array($this, 'edit_webhook'), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA), array(array($this, 'delete_webhook'), WC_API_Server::DELETABLE));
        $routes[$this->base . '/(?P<webhook_id>\\d+)/deliveries'] = array(array(array($this, 'get_webhook_deliveries'), WC_API_Server::READABLE));
        $routes[$this->base . '/(?P<webhook_id>\\d+)/deliveries/(?P<id>\\d+)'] = array(array(array($this, 'get_webhook_delivery'), WC_API_Server::READABLE));
        return $routes;
    }
    public function get_webhooks($fields = null, $filter = array(), $status = null, $page = 1)
    {
        if (!empty($status)) {
            $filter['status'] = $status;
        }
        $filter['page'] = $page;
        $query = $this->query_webhooks($filter);
        $webhooks = array();
        foreach ($query['results'] as $webhook_id) {
            $webhooks[] = current($this->get_webhook($webhook_id, $fields));
        }
        $this->server->add_pagination_headers($query['headers']);
        return array('webhooks' => $webhooks);
    }
    public function get_webhook($id, $fields = null)
    {
        $id = $this->validate_request($id, 'shop_webhook', 'read');
        if (is_wp_error($id)) {
            return $id;
        }
        $webhook = wc_get_webhook($id);
        $webhook_data = array('id' => $webhook->get_id(), 'name' => $webhook->get_name(), 'status' => $webhook->get_status(), 'topic' => $webhook->get_topic(), 'resource' => $webhook->get_resource(), 'event' => $webhook->get_event(), 'hooks' => $webhook->get_hooks(), 'delivery_url' => $webhook->get_delivery_url(), 'created_at' => $this->server->format_datetime($webhook->get_date_created() ? $webhook->get_date_created()->getTimestamp() : 0, false, false), 'updated_at' => $this->server->format_datetime($webhook->get_date_modified() ? $webhook->get_date_modified()->getTimestamp() : 0, false, false));
        return array('webhook' => apply_filters('woocommerce_api_webhook_response', $webhook_data, $webhook, $fields, $this));
    }
    public function get_webhooks_count($status = null, $filter = array())
    {
        try {
            if (!current_user_can('manage_woocommerce')) {
                throw new WC_API_Exception('woocommerce_api_user_cannot_read_webhooks_count', __('You do not have permission to read the webhooks count', 'woocommerce'), 401);
            }
            if (!empty($status)) {
                $filter['status'] = $status;
            }
            $query = $this->query_webhooks($filter);
            return array('count' => $query['headers']->total);
        } catch (WC_API_Exception $e) {
            return new WP_Error($e->getErrorCode(), $e->getMessage(), array('status' => $e->getCode()));
        }
    }
    public function create_webhook($data)
    {
        try {
            if (!isset($data['webhook'])) {
                throw new WC_API_Exception('woocommerce_api_missing_webhook_data', sprintf(__('No %1$s data specified to create %1$s', 'woocommerce'), 'webhook'), 400);
            }
            $data = $data['webhook'];
            if (!current_user_can('manage_woocommerce')) {
                throw new WC_API_Exception('woocommerce_api_user_cannot_create_webhooks', __('You do not have permission to create webhooks.', 'woocommerce'), 401);
            }
            $data = apply_filters('woocommerce_api_create_webhook_data', $data, $this);
            if (empty($data['topic']) || !wc_is_webhook_valid_topic(strtolower($data['topic']))) {
                throw new WC_API_Exception('woocommerce_api_invalid_webhook_topic', __('Webhook topic is required and must be valid.', 'woocommerce'), 400);
            }
            if (empty($data['delivery_url']) || !wc_is_valid_url($data['delivery_url'])) {
                throw new WC_API_Exception('woocommerce_api_invalid_webhook_delivery_url', __('Webhook delivery URL must be a valid URL starting with http:// or https://', 'woocommerce'), 400);
            }
            $webhook_data = apply_filters('woocommerce_new_webhook_data', array('post_type' => 'shop_webhook', 'post_status' => 'publish', 'ping_status' => 'closed', 'post_author' => get_current_user_id(), 'post_password' => 'webhook_' . wp_generate_password(), 'post_title' => !empty($data['name']) ? $data['name'] : sprintf(__('Webhook created on %s', 'woocommerce'), strftime(_x('%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce')))), $data, $this);
            $webhook = new WC_Webhook();
            $webhook->set_name($webhook_data['post_title']);
            $webhook->set_user_id($webhook_data['post_author']);
            $webhook->set_status('publish' === $webhook_data['post_status'] ? 'active' : 'disabled');
            $webhook->set_topic($data['topic']);
            $webhook->set_delivery_url($data['delivery_url']);
            $webhook->set_secret(!empty($data['secret']) ? $data['secret'] : wp_generate_password(50, true, true));
            $webhook->set_api_version('legacy_v3');
            $webhook->save();
            $webhook->deliver_ping();
            $this->server->send_status(201);
            do_action('woocommerce_api_create_webhook', $webhook->get_id(), $this);
            return $this->get_webhook($webhook->get_id());
        } catch (WC_API_Exception $e) {
            return new WP_Error($e->getErrorCode(), $e->getMessage(), array('status' => $e->getCode()));
        }
    }
    public function edit_webhook($id, $data)
    {
        try {
            if (!isset($data['webhook'])) {
                throw new WC_API_Exception('woocommerce_api_missing_webhook_data', sprintf(__('No %1$s data specified to edit %1$s', 'woocommerce'), 'webhook'), 400);
            }
            $data = $data['webhook'];
            $id = $this->validate_request($id, 'shop_webhook', 'edit');
            if (is_wp_error($id)) {
                return $id;
            }
            $data = apply_filters('woocommerce_api_edit_webhook_data', $data, $id, $this);
            $webhook = wc_get_webhook($id);
            if (!empty($data['topic'])) {
                if (wc_is_webhook_valid_topic(strtolower($data['topic']))) {
                    $webhook->set_topic($data['topic']);
                } else {
                    throw new WC_API_Exception('woocommerce_api_invalid_webhook_topic', __('Webhook topic must be valid.', 'woocommerce'), 400);
                }
            }
            if (!empty($data['delivery_url'])) {
                if (wc_is_valid_url($data['delivery_url'])) {
                    $webhook->set_delivery_url($data['delivery_url']);
                } else {
                    throw new WC_API_Exception('woocommerce_api_invalid_webhook_delivery_url', __('Webhook delivery URL must be a valid URL starting with http:// or https://', 'woocommerce'), 400);
                }
            }
            if (!empty($data['secret'])) {
                $webhook->set_secret($data['secret']);
            }
            if (!empty($data['status'])) {
                $webhook->set_status($data['status']);
            }
            if (!empty($data['name'])) {
                $webhook->set_name($data['name']);
            }
            $webhook->save();
            do_action('woocommerce_api_edit_webhook', $webhook->get_id(), $this);
            return $this->get_webhook($webhook->get_id());
        } catch (WC_API_Exception $e) {
            return new WP_Error($e->getErrorCode(), $e->getMessage(), array('status' => $e->getCode()));
        }
    }
    public function delete_webhook($id)
    {
        $id = $this->validate_request($id, 'shop_webhook', 'delete');
        if (is_wp_error($id)) {
            return $id;
        }
        do_action('woocommerce_api_delete_webhook', $id, $this);
        $webhook = wc_get_webhook($id);
        return $webhook->delete(true);
    }
    private function query_webhooks($args)
    {
        $args = $this->merge_query_args(array(), $args);
        $args['limit'] = isset($args['posts_per_page']) ? intval($args['posts_per_page']) : intval(get_option('posts_per_page'));
        if (empty($args['offset'])) {
            $args['offset'] = 1 < $args['paged'] ? ($args['paged'] - 1) * $args['limit'] : 0;
        }
        $page = $args['paged'];
        unset($args['paged'], $args['posts_per_page']);
        if (isset($args['s'])) {
            $args['search'] = $args['s'];
            unset($args['s']);
        }
        if (!empty($args['post_status'])) {
            $args['status'] = $args['post_status'];
            unset($args['post_status']);
        }
        if (!empty($args['post__in'])) {
            $args['include'] = $args['post__in'];
            unset($args['post__in']);
        }
        if (!empty($args['date_query'])) {
            foreach ($args['date_query'] as $date_query) {
                if ('post_date_gmt' === $date_query['column']) {
                    $args['after'] = isset($date_query['after']) ? $date_query['after'] : null;
                    $args['before'] = isset($date_query['before']) ? $date_query['before'] : null;
                } elseif ('post_modified_gmt' === $date_query['column']) {
                    $args['modified_after'] = isset($date_query['after']) ? $date_query['after'] : null;
                    $args['modified_before'] = isset($date_query['before']) ? $date_query['before'] : null;
                }
            }
            unset($args['date_query']);
        }
        $args['paginate'] = true;
        $data_store = WC_Data_Store::load('webhook');
        $results = $data_store->search_webhooks($args);
        $headers = new stdClass();
        $headers->page = $page;
        $headers->total = $results->total;
        $headers->is_single = $args['limit'] > $headers->total;
        $headers->total_pages = $results->max_num_pages;
        return array('results' => $results->webhooks, 'headers' => $headers);
    }
    public function get_webhook_deliveries($webhook_id, $fields = null)
    {
        $webhook_id = $this->validate_request($webhook_id, 'shop_webhook', 'read');
        if (is_wp_error($webhook_id)) {
            return $webhook_id;
        }
        return array('webhook_deliveries' => array());
    }
    public function get_webhook_delivery($webhook_id, $id, $fields = null)
    {
        try {
            $webhook_id = $this->validate_request($webhook_id, 'shop_webhook', 'read');
            if (is_wp_error($webhook_id)) {
                return $webhook_id;
            }
            $id = absint($id);
            if (empty($id)) {
                throw new WC_API_Exception('woocommerce_api_invalid_webhook_delivery_id', __('Invalid webhook delivery ID.', 'woocommerce'), 404);
            }
            $webhook = new WC_Webhook($webhook_id);
            $log = 0;
            if (!$log) {
                throw new WC_API_Exception('woocommerce_api_invalid_webhook_delivery_id', __('Invalid webhook delivery.', 'woocommerce'), 400);
            }
            return array('webhook_delivery' => apply_filters('woocommerce_api_webhook_delivery_response', array(), $id, $fields, $log, $webhook_id, $this));
        } catch (WC_API_Exception $e) {
            return new WP_Error($e->getErrorCode(), $e->getMessage(), array('status' => $e->getCode()));
        }
    }
    protected function validate_request($id, $type, $context)
    {
        $id = absint($id);
        if (empty($id)) {
            return new WP_Error("woocommerce_api_invalid_webhook_id", sprintf(__('Invalid %s ID', 'woocommerce'), $type), array('status' => 404));
        }
        $webhook = wc_get_webhook($id);
        if (null === $webhook) {
            return new WP_Error("woocommerce_api_no_webhook_found", sprintf(__('No %1$s found with the ID equal to %2$s', 'woocommerce'), 'webhook', $id), array('status' => 404));
        }
        switch ($context) {
            case 'read':
                if (!current_user_can('manage_woocommerce')) {
                    return new WP_Error("woocommerce_api_user_cannot_read_webhook", sprintf(__('You do not have permission to read this %s', 'woocommerce'), 'webhook'), array('status' => 401));
                }
                break;
            case 'edit':
                if (!current_user_can('manage_woocommerce')) {
                    return new WP_Error("woocommerce_api_user_cannot_edit_webhook", sprintf(__('You do not have permission to edit this %s', 'woocommerce'), 'webhook'), array('status' => 401));
                }
                break;
            case 'delete':
                if (!current_user_can('manage_woocommerce')) {
                    return new WP_Error("woocommerce_api_user_cannot_delete_webhook", sprintf(__('You do not have permission to delete this %s', 'woocommerce'), 'webhook'), array('status' => 401));
                }
                break;
        }
        return $id;
    }
}