<?php

/**
 * Matomo - free/libre analytics platform
 *
 * @link    https://matomo.org
 * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
 */
namespace Piwik\Plugins\SegmentEditor;

use Exception;
use Piwik\Piwik;
use Piwik\Segment;
use Piwik\Segment\SegmentExpression;
/**
 */
class SegmentFormatter
{
    /**
     * @var Segment\SegmentsList
     */
    private $segmentList;
    private $matchesMetric = array(SegmentExpression::MATCH_EQUAL => 'General_OperationEquals', SegmentExpression::MATCH_NOT_EQUAL => 'General_OperationNotEquals', SegmentExpression::MATCH_LESS_OR_EQUAL => 'General_OperationAtMost', SegmentExpression::MATCH_GREATER_OR_EQUAL => 'General_OperationAtLeast', SegmentExpression::MATCH_LESS => 'General_OperationLessThan', SegmentExpression::MATCH_GREATER => 'General_OperationGreaterThan');
    private $matchesDimension = array(SegmentExpression::MATCH_EQUAL => 'General_OperationIs', SegmentExpression::MATCH_NOT_EQUAL => 'General_OperationIsNot', SegmentExpression::MATCH_CONTAINS => 'General_OperationContains', SegmentExpression::MATCH_DOES_NOT_CONTAIN => 'General_OperationDoesNotContain', SegmentExpression::MATCH_STARTS_WITH => 'General_OperationStartsWith', SegmentExpression::MATCH_ENDS_WITH => 'General_OperationEndsWith');
    private $operators = array(SegmentExpression::BOOL_OPERATOR_AND => 'General_And', SegmentExpression::BOOL_OPERATOR_OR => 'General_Or', SegmentExpression::BOOL_OPERATOR_END => '');
    public function __construct(Segment\SegmentsList $segmentList)
    {
        $this->segmentList = $segmentList;
    }
    public function getHumanReadable($segmentString, $idSite)
    {
        if (empty($segmentString)) {
            return Piwik::translate('SegmentEditor_DefaultAllVisits');
        }
        try {
            $segment = new SegmentExpression(urldecode($segmentString));
            $expressions = $segment->parseSubExpressions();
        } catch (Exception $e) {
            $segment = new SegmentExpression($segmentString);
            $expressions = $segment->parseSubExpressions();
        }
        $readable = '';
        foreach ($expressions as $andIndex => $orExpressions) {
            foreach ($orExpressions as $orIndex => $operand) {
                $name = $operand[SegmentExpression::INDEX_OPERAND_NAME];
                $segment = $this->segmentList->getSegment($name);
                if (empty($segment)) {
                    throw new Exception(sprintf("The segment '%s' does not exist.", $name));
                }
                $readable .= Piwik::translate($segment->getName()) . ' ';
                $readable .= $this->getTranslationForComparison($operand, $segment->getType()) . ' ';
                $readable .= $this->getFormattedValue($operand);
                if ($orIndex !== count($orExpressions) - 1) {
                    $readable .= $this->getTranslationForBoolOperator(SegmentExpression::BOOL_OPERATOR_OR) . ' ';
                }
            }
            if ($andIndex !== count($expressions) - 1) {
                $readable .= $this->getTranslationForBoolOperator(SegmentExpression::BOOL_OPERATOR_AND) . ' ';
            }
        }
        $readable = trim($readable);
        return $readable;
    }
    private function getTranslationForComparison($operand, $segmentType)
    {
        $operator = $operand[SegmentExpression::INDEX_OPERAND_OPERATOR];
        $translation = $operator;
        if ($operator === SegmentExpression::MATCH_IS_NULL_OR_EMPTY) {
            return Piwik::translate('SegmentEditor_SegmentOperatorIsNullOrEmpty');
        }
        if ($operator === SegmentExpression::MATCH_IS_NOT_NULL_NOR_EMPTY) {
            return Piwik::translate('SegmentEditor_SegmentOperatorIsNotNullNorEmpty');
        }
        if ($segmentType === 'dimension' && !empty($this->matchesDimension[$operator])) {
            $translation = Piwik::translate($this->matchesDimension[$operator]);
        }
        if ($segmentType === 'metric' && !empty($this->matchesMetric[$operator])) {
            $translation = Piwik::translate($this->matchesMetric[$operator]);
        }
        return mb_strtolower($translation);
    }
    private function getFormattedValue($operand)
    {
        $operator = $operand[SegmentExpression::INDEX_OPERAND_OPERATOR];
        if ($operator === SegmentExpression::MATCH_IS_NULL_OR_EMPTY || $operator === SegmentExpression::MATCH_IS_NOT_NULL_NOR_EMPTY) {
            return '';
        }
        $value = $operand[SegmentExpression::INDEX_OPERAND_VALUE];
        if (empty($value)) {
            $value = '';
        }
        return '"' . $value . '" ';
    }
    private function getTranslationForBoolOperator($operator)
    {
        $translation = '';
        if (!empty($this->operators[$operator])) {
            $translation = Piwik::translate($this->operators[$operator]);
        } elseif (!empty($operator)) {
            $translation = $operator;
        }
        return $translation;
    }
}
