1<?php
2
3/*
4 * This file is part of the Prophecy.
5 * (c) Konstantin Kudryashov <ever.zet@gmail.com>
6 *     Marcello Duarte <marcello.duarte@gmail.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Prophecy\Argument;
13
14/**
15 * Arguments wildcarding.
16 *
17 * @author Konstantin Kudryashov <ever.zet@gmail.com>
18 */
19class ArgumentsWildcard
20{
21    /**
22     * @var Token\TokenInterface[]
23     */
24    private $tokens = array();
25    private $string;
26
27    /**
28     * Initializes wildcard.
29     *
30     * @param array $arguments Array of argument tokens or values
31     */
32    public function __construct(array $arguments)
33    {
34        foreach ($arguments as $argument) {
35            if (!$argument instanceof Token\TokenInterface) {
36                $argument = new Token\ExactValueToken($argument);
37            }
38
39            $this->tokens[] = $argument;
40        }
41    }
42
43    /**
44     * Calculates wildcard match score for provided arguments.
45     *
46     * @param array $arguments
47     *
48     * @return false|int False OR integer score (higher - better)
49     */
50    public function scoreArguments(array $arguments)
51    {
52        if (0 == count($arguments) && 0 == count($this->tokens)) {
53            return 1;
54        }
55
56        $arguments  = array_values($arguments);
57        $totalScore = 0;
58        foreach ($this->tokens as $i => $token) {
59            $argument = isset($arguments[$i]) ? $arguments[$i] : null;
60            if (1 >= $score = $token->scoreArgument($argument)) {
61                return false;
62            }
63
64            $totalScore += $score;
65
66            if (true === $token->isLast()) {
67                return $totalScore;
68            }
69        }
70
71        if (count($arguments) > count($this->tokens)) {
72            return false;
73        }
74
75        return $totalScore;
76    }
77
78    /**
79     * Returns string representation for wildcard.
80     *
81     * @return string
82     */
83    public function __toString()
84    {
85        if (null === $this->string) {
86            $this->string = implode(', ', array_map(function ($token) {
87                return (string) $token;
88            }, $this->tokens));
89        }
90
91        return $this->string;
92    }
93
94    /**
95     * @return array
96     */
97    public function getTokens()
98    {
99        return $this->tokens;
100    }
101}
102