import sys
import select
import os

def read_line():
    buf = ""
    while True:
        r, _, _ = select.select([sys.stdin], [], [], 0.05)
        if r:
            char = sys.stdin.read(1)
            if char in ('\r', '\n'):
                console.write('\n')
                return buf
            elif char == '\b' or ord(char) == 127:
                if len(buf) > 0:
                    buf = buf[:-1]
                    console.write('\b')
            else:
                buf += char
                console.write(char)

def print_lines(lines, start, end):
    start = max(0, start - 1)
    end = min(len(lines), end)
    for i in range(start, end):
        console.write("{:3}: {}\n".format(i + 1, lines[i]))

def file_exists(f):
    try:
        os.stat(f)
        return True
    except: return False

def main():
    if 'sys_argv' not in globals() or len(sys_argv) < 2:
        console.write("Syntaxe: edlin <fichier>\n")
        return

    filename = sys_argv[1]
    lines = []
    current_line = 1
    
    if file_exists(filename):
        try:
            with open(filename, "r") as f:
                content = f.read()
                if content:
                    lines = content.split('\n')
                    if lines and lines[-1] == '':
                        lines.pop()
            console.write("Fichier charge. {} ligne(s).\n".format(len(lines)))
        except:
            console.write("Erreur de lecture du fichier.\n")
            return
    else:
        console.write("Nouveau fichier.\n")

    dirty = False

    while True:
        console.write("*")
        cmd = read_line().strip().upper()
        
        if not cmd: continue
            
        if cmd in ('H', '?', 'HELP'):
            console.write("L       : Lister tout le fichier\n")
            console.write("x,yL    : Lister lignes x a y\n")
            console.write("I       : Inserer avant ligne courante\n")
            console.write("xI      : Inserer avant ligne x\n")
            console.write("D       : Supprimer ligne courante\n")
            console.write("x,yD    : Supprimer lignes x a y\n")
            console.write("S       : Sauvegarder\n")
            console.write("E       : Sauvegarder et Quitter\n")
            console.write("Q       : Quitter sans sauvegarder\n")
            console.write("<num>   : Editer ligne specifique\n")
            continue

        if cmd == 'Q':
            if dirty:
                console.write("Quitter sans sauvegarder ? (O/N) ")
                ans = read_line().strip().upper()
                if ans != 'O': continue
            break
            
        elif cmd == 'E' or cmd == 'S':
            try:
                with open(filename, "w") as f:
                    for l in lines:
                        f.write(l + "\n")
                dirty = False
                console.write("Sauvegarde terminee.\n")
                if cmd == 'E': break
            except:
                console.write("Erreur d'ecriture.\n")
                
        elif cmd.endswith('L'):
            parts = cmd[:-1].split(',')
            start = 1
            end = len(lines)
            if len(parts) >= 1 and parts[0]:
                try: start = int(parts[0])
                except: pass
            if len(parts) >= 2 and parts[1]:
                try: end = int(parts[1])
                except: pass
            print_lines(lines, start, end)
            
        elif cmd.endswith('I'):
            idx = current_line - 1
            parts = cmd[:-1]
            if parts:
                try: idx = int(parts) - 1
                except: pass
            idx = max(0, min(len(lines), idx))
            
            while True:
                console.write("{:3}:*".format(idx + 1))
                new_l = read_line()
                if new_l == ".":
                    break
                lines.insert(idx, new_l)
                idx += 1
                dirty = True
                
        elif cmd.endswith('D'):
            parts = cmd[:-1].split(',')
            start = current_line
            end = current_line
            if len(parts) >= 1 and parts[0]:
                try: start = int(parts[0])
                except: pass
            if len(parts) >= 2 and parts[1]:
                try: end = int(parts[1])
                except: pass
            else:
                end = start
                
            start_idx = max(0, start - 1)
            end_idx = min(len(lines), end)
            if start_idx < end_idx:
                del lines[start_idx:end_idx]
                dirty = True
                console.write("Ligne(s) supprimee(s).\n")
                
        else:
            try:
                num = int(cmd)
                if 1 <= num <= len(lines):
                    console.write("{:3}: {}\n".format(num, lines[num-1]))
                    console.write("{:3}:*".format(num))
                    new_l = read_line()
                    if new_l != "":
                        lines[num-1] = new_l
                        dirty = True
                    current_line = num
                else:
                    console.write("Ligne introuvable.\n")
            except:
                console.write("Commande inconnue.\n")

main()
