<?php

declare(strict_types=1);

namespace App\Framework\Serializer;

use App\Framework\Serializer\Json\JsonSerializer;
use App\Framework\Serializer\Json\JsonSerializerConfig;
use App\Framework\Serializer\Php\PhpSerializer;
use App\Framework\Serializer\Php\PhpSerializerConfig;

/**
 * Factory for creating serializer instances
 *
 * This class provides methods for creating various serializer instances.
 */
final class SerializerFactory
{
    /**
     * Creates a JSON serializer with default settings
     *
     * @return Serializer
     */
    public static function createJsonSerializer(): Serializer
    {
        return new JsonSerializer();
    }

    /**
     * Creates a JSON serializer with pretty printing
     *
     * @return Serializer
     */
    public static function createPrettyJsonSerializer(): Serializer
    {
        return new JsonSerializer(JsonSerializerConfig::pretty());
    }

    /**
     * Creates a JSON serializer with compact output
     *
     * @return Serializer
     */
    public static function createCompactJsonSerializer(): Serializer
    {
        return new JsonSerializer(JsonSerializerConfig::compact());
    }

    /**
     * Creates a JSON serializer with minimal settings
     *
     * @return Serializer
     */
    public static function createMinimalJsonSerializer(): Serializer
    {
        return new JsonSerializer(JsonSerializerConfig::minimal());
    }

    /**
     * Creates a JSON serializer with custom settings
     *
     * @param int $flags JSON encoding flags
     * @param int $depth Maximum depth for encoding/decoding
     * @return Serializer
     */
    public static function createCustomJsonSerializer(int $flags, int $depth = 512): Serializer
    {
        return new JsonSerializer(new JsonSerializerConfig($flags, $depth));
    }

    /**
     * Creates a PHP serializer with default settings (safe with no allowed classes)
     *
     * @return Serializer
     */
    public static function createPhpSerializer(): Serializer
    {
        return new PhpSerializer();
    }

    /**
     * Creates a PHP serializer with safe deserialization (only specified classes allowed)
     *
     * @param array $allowedClasses List of class names that are allowed to be unserialized
     * @return Serializer
     */
    public static function createSafePhpSerializer(array $allowedClasses = []): Serializer
    {
        return new PhpSerializer(PhpSerializerConfig::safe($allowedClasses));
    }

    /**
     * Creates a PHP serializer with unsafe deserialization (all classes allowed)
     *
     * @return Serializer
     */
    public static function createUnsafePhpSerializer(): Serializer
    {
        return new PhpSerializer(PhpSerializerConfig::unsafe());
    }

    /**
     * Creates a PHP serializer with custom options
     *
     * @param bool|array $allowedClasses Controls which classes are allowed to be unserialized
     * @param int $maxDepth Maximum depth of nested objects to deserialize
     * @return Serializer
     */
    public static function createCustomPhpSerializer(bool|array $allowedClasses, int $maxDepth = 4096): Serializer
    {
        return new PhpSerializer(new PhpSerializerConfig($allowedClasses, $maxDepth));
    }
}
