<?php
/**
 * Copyright 2020 Adobe
 * All Rights Reserved.
 *
 * NOTICE: Adobe permits you to use, modify, and distribute this file in
 * accordance with the terms of the Adobe license agreement accompanying
 * it.
 */
declare(strict_types=1);

namespace Magento\Mray\CodeStructuralElement\Php;

use Magento\Mray\CodeStructuralElement\Php\Reflection\ClassLikeDeclaration;
use Magento\Mray\CodeStructuralElement\Php\Reflection\ConstantDeclaration;
use Magento\Mray\CodeStructuralElement\Php\Reflection\TypeFactory;
use Magento\Mray\CodeStructuralElement\FullQualifiedStructuralElementName;
use phpDocumentor\Reflection\Type;
use phpDocumentor\Reflection\Types;

class ClassLikeConstant extends ClassLikeMember
{
    /**
     * @var object
     */
    private $cGrp;
    /**
     * @var object
     */
    private $c;

    /**
     * @param ClassLikeDeclaration $cl
     * @param ConstantDeclaration\ClassConst $const
     */
    public function __construct(
        ClassLikeDeclaration $cl,
        ConstantDeclaration\ClassConst $const
    ) {
        parent::__construct($cl);
        $this->cGrp = (object)[
            'isPrivate' => $const->isPrivate(),
            'isPublic' => $const->isPublic(),
        ];
        $this->c = (object)[
            'name' => $const->getName(),
            'checksum' => $const->getImplementationChecksum(),
            'value' => (object)[
                'runtimeType' => $const->getValueType()
            ]
        ];
    }

    /**
     * @param PhpFqsen\ClassLike $className
     * @return FullQualifiedStructuralElementName
     */
    public function createAlias(PhpFqsen\ClassLike $className): FullQualifiedStructuralElementName
    {
        return new PhpFqsen\ClassLikeConstant(
            $className->pretty(),
            (string)$this->c->name
        );
    }

    /**
     * @return string
     */
    public function getType(): string
    {
        return 'Php_Constant_ClassLike';
    }

    /**
     * @return Type
     */
    public function getValueType(): Type
    {
        return $this->c->value->runtimeType ?? TypeFactory::get(Types\Scalar::class);
    }

    /**
     * @return bool
     */
    public function isPrivate(): bool
    {
        return $this->cGrp->isPrivate;
    }

    /**
     * @return bool
     */
    public function isPublic(): bool
    {
        return $this->cGrp->isPublic;
    }

    /**
     * @return string|null
     */
    public function getChecksum(): ?string
    {
        return $this->c->checksum;
    }
}
