<?php

namespace App\Factories;

use Illuminate\Database\Eloquent\Factories\Factory as ParentFactory;
use Illuminate\Support\Str;

abstract class Factory extends ParentFactory
{
    /**
     * Custom namespace for models.
     * @var string
     */
    public static $customNameSpaceForModels = 'ProcessMaker\\Model\\';

    /**
     * Custom directory for models.
     * @var string
     */
    public static $customDirectoryForModels = 'workflow/engine/src/ProcessMaker/Model/';

    /**
     * Get the factory name for the given model name.
     *
     * @param  string  $modelName
     * @return string
     */
    public static function resolveFactoryName(string $modelName)
    {
        $resolver = static::$factoryNameResolver ?: function (string $modelName) {
            $appNamespace = static::appNamespace();

            $modelName = Str::startsWith($modelName, $appNamespace.'Models\\')
                ? Str::after($modelName, $appNamespace.'Models\\')
                : (Str::startsWith($modelName, static::$customNameSpaceForModels)
                    ? Str::after($modelName, static::$customNameSpaceForModels)
                    : Str::after($modelName, $appNamespace));

            return static::$namespace.$modelName.'Factory';
        };

        return $resolver($modelName);
    }
    
    /**
     * Get the name of the model that is generated by the factory.
     *
     * @return string
     */
    public function modelName()
    {
        $resolver = static::$modelNameResolver ?: function (self $factory) {
            $namespacedFactoryBasename = Str::replaceLast(
                'Factory', '', Str::replaceFirst(static::$namespace, '', get_class($factory))
            );

            $factoryBasename = Str::replaceLast('Factory', '', class_basename($factory));

            $appNamespace = static::appNamespace();

            return class_exists($appNamespace.'Models\\'.$namespacedFactoryBasename)
                        ? $appNamespace.'Models\\'.$namespacedFactoryBasename
                        : (class_exists(static::$customNameSpaceForModels.$namespacedFactoryBasename)
                            ? static::$customNameSpaceForModels.$namespacedFactoryBasename
                            : $appNamespace.$factoryBasename);
        };

        return $this->model ?: $resolver($this);
    }
}
