<?php

interface Command
{
    public function handle() : void;
}



final class CreateListing implements Command
{
    private const MIN_TITLE_LENGTH = 10;
    private const MIN_CONTENT_LENGTH = 15;
    private const MIN_AUTHOR_LENGTH = 5;
    private $repository;
    private $title;
    private $content;
    private $author;

    public function __construct(ListingRepository $repository, string $title, string $content, string $author)
    {
        $this->repository = $repository;
        $this->title = $title;
        $this->content = $content;
        $this->author = $author;
    }

    private function validate(): void
    {
        if (strlen($this->title) < self::MIN_TITLE_LENGTH) {
            throw new LengthException(sprintf("Title is too short. Must be at least %d characters",
                self::MIN_TITLE_LENGTH));
        }
        if (strlen($this->content) < self::MIN_CONTENT_LENGTH) {
            throw new LengthException(sprintf("Content is too short. Must be at least %d characters",
                self::MIN_CONTENT_LENGTH));
        }
        if (strlen($this->author) < self::MIN_AUTHOR_LENGTH) {
            throw new LengthException(sprintf("Author name is too short. Must be at least %d characters",
                self::MIN_AUTHOR_LENGTH));
        }
    }

    public function handle(): void
    {
        $this->validate();
        $this->repository->create($this->title, $this->content, $this->author);
    }
}


final class DeleteListing implements Command
{
    private $repository;
    private $listingUid;

    public function __construct(ListingRepository $repository, string $listingUid)
    {
        $this->repository = $repository;
        $this->listingUid = $listingUid;
    }

    public function handle(): void
    {
        $this->repository->delete($this->listingUid);
    }
}

final class ListingRepository
{
    public function create(string $title, string $content, string $author): void
    {
        echo sprintf("Creating new listing by \"%s\" and title \"%s\"", $author, $title).PHP_EOL;
        echo sprintf("Content: \"%s\"", $content).PHP_EOL;
        echo sprintf("Generated uid: \"%s\"", uniqid()).PHP_EOL;
    }

    public function delete(string $uid): void
    {
        echo sprintf("Removing job listing with uid: \"%s\"", $uid).PHP_EOL;
    }
}


final class Client
{
    private $listingRepository;

    public function __construct(ListingRepository $repository)
    {
        $this->listingRepository = $repository;
    }

    public function createListing(string $title, string $content, string $author): void
    {
        $command = new CreateListing($this->listingRepository, $title, $content, $author);
        $command->handle();
    }

    public function deleteListing(string $listingUid) : void
    {
        $command = new DeleteListing($this->listingRepository, $listingUid);
        $command->handle();
    }

}


$client = new Client(new ListingRepository());
$client->createListing(
    "New job listing",
    "This is a content of a listing",
    "Company"
);
$client->deleteListing("Unique id");