<?php

/**
 * Class representing restaurant
 */
class Restaurant {

    private $url;
    private $name;
    private $xpaths = array();

    public function getName() {
        return $this->name;
    }

    public function getUrl() {
        return $this->url;
    }

    public function getXpaths() {
        return $this->xpaths;
    }

    /**
     * @param $name
     * @param $url
     * @param $xpaths
     */
    function __construct($name, $url, $xpaths) {

        if (empty($url) || empty($xpaths)) {
            throw new InvalidArgumentException("All argument are required");
        }

        $this->name = $name;
        $this->url = $url;

        if (is_string($xpaths)) {
            $this->xpaths[] = $xpaths;
        } else if (is_array($xpaths)) {
            $this->xpaths = $xpaths;
        } else {
            throw new InvalidArgumentException("Xpaths must be string or array");
        }
    }

}

interface iOutput {
    public function log($message);
    public function display();
}

class Output implements iOutput {
    protected $output = "";

    public function log($message) {
        $this->output .= $message;
    }

    public function display(){}
}

class HtmlOutput extends Output  {

    public function display(){
        echo $this->output;
    }
}

class EmailOutput {

    public function display(){
        // Send mail
    }
}


class Parser {

    private $restaurants = array();
    private $logger;

    function __construct($logger, $restaurants) {

        // Check if logger implements iOutput interface
        if (  !in_array("iOutput", class_implements($logger)) ) {
            throw new InvalidArgumentException("Logger class must implement interface iOutput");
        }

        $this->logger = $logger;

        if (empty($restaurants) || !is_array($restaurants)) {
            throw new InvalidArgumentException("Array argument required");
        }

        $this->restaurants = $restaurants;
    }

    public function parse() {
        foreach ($this->restaurants as $restaurant) {

            $source = file_get_contents($restaurant->getUrl());

            if ($source === false) {
                throw new RuntimeException("Can't read source address: " . $restaurant->getUrl());
            }

            $dom = new DOMDocument();
            @$dom->loadHTML($source);
            $xpath_obj = new DOMXPath($dom);

            $this->logger->log("Restaurant: <a href='{$restaurant->getUrl()}'>" . $restaurant->getName() . "</a><br>\n");

            foreach ($restaurant->getXpaths() as $name => $xpath) {

                $found = $xpath_obj->query($xpath);

                if ($found === false || $found->length === 0) {
                    continue;
                }

                $this->logger->log("<b>$name</b>");
                $exists = false;
                foreach ($found->item(0)->childNodes as $elem) {

                    $meal = trim($elem->nodeValue);
                    if (!empty($meal)) {
                        $this->logger->log("\t<br>$meal\n");
                        $exists = true;
                    }
                }
                if (!$exists) {
                    $this->logger->log("<br>{}");
                }
                $this->logger->log("<br>");
            }
            $this->logger->log("<br>");
        }
    }


}

$twenties = new Restaurant("Twenties", "http://www.twenties.sk/", array("Polievky" => '//*[@id="article"]/div[2]/p[1]'));
$pulitzer = new Restaurant("Pulitzer", "http://www.pulitzer.sk",
    array("Polievky" => '//*[@id="soups"]',
        "Hlavne jedla" => '//*[@id="meals"]'));
$slovak = new Restaurant("Slovak pub", "http://www.arcaderestaurant.sk/articles/public_menu/show-modules/id/24",
    array("Salat" => '//*[@id="table2"]/tbody/tr[10]',
        "Polievka" => '//*[@id="table2"]/tbody/tr[2]'));


$htmlOutput = new HtmlOutput();
$parser = new Parser($htmlOutput, array($twenties, $pulitzer, $slovak));
$parser->parse();
$htmlOutput->display();



/**
 * Lebo bez masa nie je den dnom. Maso je sucast jedla, preto chodim jest do
 * blizkych malych restauracii.
 */

/*

$sites  = [
        'Pulitzer'      => 'http://pulitzer.sk/',
        'Twenties'      => 'http://www.twenties.sk/'
];

$xpaths = [
        'Pulitzer'      => [
                'Polievky'                      =>      '//*[@id="soups"]',
                'Hlavne zradla'         =>      '//*[@id="meals"]'
        ],
        'Twenties'      => [
                'Polievka + hlavne zradla'      => '//*[@id="article"]/div[2]/p[1]'
        ]
];

$output_file = '/tmp/results.php';
file_put_contents($output_file, '');

$dom = new DOMDocument();

foreach ($sites as $restaurant => $site)
{
        @$dom->loadHTML(file_get_contents($site));
        $xpath_obj = new DOMXPath($dom);

        append_result('V tovarni na jedlo s nazvom *' . $restaurant . "* maju dneska toto: \n");

        foreach ($xpaths[$restaurant] as $human_meal => $xpath)
        {
                append_result("\t$human_meal:\n");

                $oh_my_god_here_are_saved_meals = $xpath_obj->query($xpath);
                if ($oh_my_god_here_are_saved_meals === FALSE
                        OR $oh_my_god_here_are_saved_meals->length === 0)
                {
                        continue;
                }

                $found_meal = FALSE;
        foreach ($oh_my_god_here_are_saved_meals->item(0)->childNodes as $elem)
                {
                        $meal_meal_meal = trim($elem->nodeValue);
                        if (! empty($meal_meal_meal))
                        {
                                append_result("\t\t$meal_meal_meal\n");
                                $found_meal = TRUE;
                        }
                }

                if (! $found_meal)
                {
                        append_result("\tNevaria!!! Daj mi niekto gulomet, nech ich zabijem!\n");
                }
                else
                {
                        append_result("\n");
                }
        }
}

append_result("\n\nMake me better on http://git.cinan.sk/obedparser.git/ :) \n");

function append_result($text)
{
        global $output_file;
        file_put_contents($output_file, $text, FILE_APPEND | FILE_TEXT);
}

*/