<?php
/**
 * Writes a row to the crawler log table.
 *
 * @package WPLens
 */

namespace WPLens\Crawler;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

final class Logger {

	/**
	 * @param array{
	 *   bot_slug:string,
	 *   bot_family:string,
	 *   user_agent:string,
	 *   request_uri:string,
	 *   request_method:string,
	 *   response_code:int,
	 *   ip:string
	 * } $data
	 */
	public function log( array $data ): int {
		global $wpdb;
		$table = $wpdb->prefix . 'wplens_crawler_log';

		$ip_hash = '';
		if ( '' !== $data['ip'] ) {
			$salt    = (string) get_option( 'wplens_ip_salt', '' );
			$ip_hash = hash( 'sha256', $salt . '|' . $data['ip'] );
		}

		$post_id = $this->resolve_post_id( $data['request_uri'] );

		$row = array(
			'visited_at'     => current_time( 'mysql', true ),
			'bot_slug'       => substr( $data['bot_slug'], 0, 64 ),
			'bot_family'     => substr( $data['bot_family'], 0, 32 ),
			'user_agent'     => substr( $data['user_agent'], 0, 512 ),
			'request_uri'    => substr( $data['request_uri'], 0, 2048 ),
			'request_method' => substr( $data['request_method'], 0, 8 ),
			'response_code'  => absint( $data['response_code'] ),
			'ip_hash'        => $ip_hash,
			'post_id'        => $post_id,
		);

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery
		$result = $wpdb->insert( $table, $row );

		return false === $result ? 0 : (int) $wpdb->insert_id;
	}

	/**
	 * Try to resolve a post ID from a request URI.
	 */
	private function resolve_post_id( string $uri ): ?int {
		$path = wp_parse_url( $uri, PHP_URL_PATH );
		if ( ! $path || '/' === $path ) {
			return null;
		}
		$url     = home_url( $path );
		$post_id = url_to_postid( $url );
		return $post_id > 0 ? $post_id : null;
	}
}
