#!/usr/bin/env python3
"""foldctl — fold long lines on word boundaries, keeping indent and comment markers."""

import argparse
import sys

VERSION = "foldctl 0.9.1"

MARKERS = ("#", "//", "*", ";", "--")

def fold_line(line, width, use_markers):
    if len(line) <= width:
        return [line]
    indent = line[:len(line) - len(line.lstrip())]
    s = line.lstrip()
    mark = ""
    if use_markers:
        for m in MARKERS:
            if s.startswith(m):
                mark = m
                break
    cont = indent + (mark + " " if mark else "")
    words = s.split()
    if mark and words and words[0].startswith(mark):
        words = words[1:]   # the marker is re-attached to every line
    out, curw, curlen = [], [], len(cont)
    for w in words:
        add = len(w) + (1 if curw else 0)
        if curw and curlen + add > width:
            out.append(cont + " ".join(curw))
            curw, curlen = [], len(cont)
            add = len(w)
        curw.append(w)
        curlen += add
    if curw:
        out.append(cont + " ".join(curw))
    return out

def run(lines, width, use_markers=True):
    out = []
    for ln in lines:
        out.extend(fold_line(ln, width, use_markers))
    return "\n".join(out) + ("\n" if out else "")

def main(argv=None):
    ap = argparse.ArgumentParser(prog="foldctl", description="Fold long lines, keep indent & markers.")
    ap.add_argument("-w", "--width", type=int, default=79)
    ap.add_argument("--no-markers", action="store_true")
    ap.add_argument("--version", action="version", version=VERSION)
    ap.add_argument("files", nargs="*")
    ns = ap.parse_args(argv)
    if ns.width < 10:
        print("foldctl: width must be >= 10", file=sys.stderr)
        return 2
    text = sys.stdin.read() if not ns.files else "".join(
        open(f, encoding="utf-8", errors="replace").read() for f in ns.files)
    sys.stdout.write(run(text.splitlines(), ns.width, not ns.no_markers))
    return 0

if __name__ == "__main__":
    sys.exit(main())
