# {{{ imports
import re
# }}}

detector_state = {"active": None}


# {{{ check_for_flag
def check_for_flag(text: str, pattern: str | None = None) -> list[str]:
    """Scans the text for all flags matching the provided pattern, the active format, or a generic pattern.
    Returns a list of matching flags found.
    """
    if not text:
        return []
        
    patterns = []
    if pattern:
        patterns.append(pattern.strip("^$"))
    else:
        try:
            from ctf.config import load_config
            config = load_config()
            flag_format = config.get("Competition", {}).get("flag_format", "")
        except Exception:
            flag_format = ""
        if flag_format:
            patterns.append(flag_format.strip("^$"))
            
    patterns.append(r"(?i)[a-z0-9_-]+{[a-z0-9_!@#$%^&*()\-+=]+}")
    
    found = []
    for pat in patterns:
        for match in re.finditer(pat, text):
            found.append(match.group(0))
            
    return list(set(found))
# }}}

# {{{ is_valid_flag
def is_valid_flag(s: str, original: str = "") -> bool:
    """
    Checks if the string contains a flag matching the active pattern or a generic pattern.
    If original is provided, ensures that the decoded string contains a new unique flag 
    that was not already present in the original string.
    """
    flags = check_for_flag(s)
    if not flags:
        return False
    if original:
        original_flags = set(check_for_flag(original))
        # If there are no new flags in decoded flags, return False
        if not (set(flags) - original_flags):
            return False
    return True
# }}}

# {{{ FlagDetectorStream
class FlagDetectorStream:
    """Intercepts stdout to scan output for matching flag formats."""
    def __init__(self, original_stream, pattern_str):
        self.original_stream = original_stream
        self._flag_buffer = ""
        self.detecting = True
        self.pattern_str = pattern_str
            
    def write(self, data):
        self.original_stream.write(data)
        if self.detecting and self.pattern_str:
            self._flag_buffer += data
            matches = check_for_flag(self._flag_buffer, self.pattern_str)
            if matches:
                self.detecting = False
                self.original_stream.write("\n\033[1;32m[!] Potential flag(s) detected in command output:\033[0m\n")
                for match in matches:
                    self.original_stream.write(f"  \033[1;32m✓ {match}\033[0m\n")
                    try:
                        from ctf.config import load_config, write_config
                        config_path = "/home/venus/code/ctf/config.toml"
                        config = load_config(config_path)
                        if "Competition" not in config:
                            config["Competition"] = {}
                        config["Competition"]["last_flag"] = match
                        write_config(config, config_path)
                    except Exception:
                        pass
                self._flag_buffer = ""
                self.detecting = True
                
    def flush(self):
        self.original_stream.flush()

    def __getattr__(self, name):
        return getattr(self.original_stream, name)
# }}}


