<?php

namespace Acms\Services\StaticExport\Contracts;

use Uri\WhatWg\Url as WhatWgUrl;

abstract class Resolver
{
    /**
     * @param string $html
     * @param string $document_root
     * @param string $offset_dir
     * @param string $domain
     * @param string $blog_code
     *
     * @return string
     */
    abstract public function resolve($html, $document_root, $offset_dir, $domain, $blog_code);

    /**
     * URLからポート番号を削除する
     *
     * WHATWG URL パーサーを使うため、日本語パスを含む URL も安全に処理できる。
     * 相対パス（/path など）は parse() が null を返すためそのまま返す。
     *
     * @param string $url
     * @return string
     */
    protected function removePortFromUrl(string $url): string
    {
        $parsed = WhatWgUrl::parse($url);
        if ($parsed === null) {
            return $url;
        }
        return $parsed->withPort(null)->toAsciiString();
    }

    /**
     * CMS の設置ディレクトリ（DIR_OFFSET）を返す
     *
     * グローバル定数への依存をこのメソッドに閉じ、テストから差し替えられるようにする。
     *
     * @return string
     */
    protected function getDirOffset(): string
    {
        return DIR_OFFSET;
    }

    /**
     * ルート相対パスの先頭から CMS の設置ディレクトリ（DIR_OFFSET）を取り除く
     *
     * 書き出し先のオフセットディレクトリは書き換え時に付け直すため、ここで取り除かないと
     * パスが二重（/sub/sub/... ）になる。DIR_OFFSET で始まらないパスはそのまま返す。
     *
     * @param string $path 先頭のスラッシュを除いたルート相対パス
     * @return string
     */
    protected function stripDirOffset(string $path): string
    {
        $dirOffset = ltrim($this->getDirOffset(), '/');
        if ($dirOffset === '' || strpos($path, $dirOffset) !== 0) {
            return $path;
        }
        return substr($path, strlen($dirOffset));
    }
}
