# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========

from mirage.accessor.base import Accessor, NOOPAccessor
from mirage.commands.registry import command
from mirage.commands.spec import SPECS
from mirage.io.types import ByteSource, IOResult
from mirage.types import PathSpec


def _seq_generate(texts: tuple[str, ...], separator: str, width: str | None,
                  fmt: str | None) -> str:
    nums = [float(t) for t in texts]
    if len(nums) == 1:
        first, step, last = 1, 1, int(nums[0])
    elif len(nums) == 2:
        first, step, last = int(nums[0]), 1, int(nums[1])
    else:
        first, step, last = int(nums[0]), int(nums[1]), int(nums[2])
    values: list[int] = []
    cur = first
    if step > 0:
        while cur <= last:
            values.append(cur)
            cur += step
    elif step < 0:
        while cur >= last:
            values.append(cur)
            cur += step
    if fmt is not None:
        parts = [fmt % v for v in values]
    elif width is not None:
        w = len(str(max(abs(v) for v in values))) if values else 1
        parts = [str(v).zfill(w) for v in values]
    else:
        parts = [str(v) for v in values]
    return separator.join(parts) + "\n"


@command("seq", resource=None, spec=SPECS["seq"])
async def seq(
    accessor: Accessor = NOOPAccessor(),
    paths: list[PathSpec] | None = None,
    *texts: str,
    stdin: bytes | None = None,
    s: str | None = None,
    w: str | None = None,
    f: str | None = None,
    **_extra: object,
) -> tuple[ByteSource | None, IOResult]:
    separator = s if s is not None else "\n"
    result = _seq_generate(texts, separator, w, f)
    return result.encode(), IOResult()
