from typing import List
from typing import Tuple


def load_domain_alignments(file: str) -> List[Tuple[str, str]]:
    """
    Parse the output file of hmmscan and load domain alignments.

    Example of alignments:
  == domain 1  score: 25.3 bits;  conditional E-value: 5.2e-09
                   Cytochrome_c4  11 llalaalal.alaaaadaeagaaklaea......gaaavkaCaaCHGadGnsaaaaayPrLAgqsaaYlakqLkdfrsg 82
                                     l++l+a+++ ++ a+++ e++a+k++ea       +   ++C +CHG+d ++a+    P+L    ++Y +++++++ ++
  Cytochrome_Bsub_c550-consensus  18 LVVLLAVNGgSKDAEEEKEEEAEKSEEAeaeaegEEIFKQKCISCHGKDLEGAVG---PNLEKVGSKYSEEEIAKIIEN 93
                                     34444444442223333333333333336666856777899***********766...***************999887 PP

                   Cytochrome_c4  83 errknpMaplakaLsdqdiedlaaYfaaq 111
                                        k +M   a+  sd++ +++a+++a++
  Cytochrome_Bsub_c550-consensus  94 G--KGAM--PAAIVSDDEAKAVAKWLAEK 118
                                     3..3344..46678999999999999986 PP

    Since the sequence is too long, the domain is represented with two "blocks".
    The "== domain" line might be followed by a consensus structure annotation line (not the case here).
    Each block has four lines:
        1. consensus of the target profile
        2. matches between the query sequence and target profile (**can be empty**)
        3. query sequence
        4. posterior probability of each aligned residue

    :param file: hmmscan output file
    :return: a list of alignments, represented by a tuple of two sequences (query, target)
    """
    alignments = []
    query_seq = target_seq = ""
    with open(file, "rt") as fh:
        for line in fh:
            line = line.strip()
            if not line:
                continue

            if line.startswith(">> "):
                # New model
                # target_name = line[3:]
                if query_seq:
                    alignments.append((query_seq, target_seq))
                    query_seq = target_seq = ""
            elif line.startswith("== domain"):
                # New domain
                if query_seq:
                    alignments.append((query_seq, target_seq))
                    query_seq = target_seq = ""

                line = next(fh).strip()
                block = []
                while line or len(block) < 4:
                    block.append(line)
                    line = next(fh).strip()

                del block[:-4]
                target_seq += block[0].split()[2]
                query_seq += block[2].split()[2]
            elif line == "Internal pipeline statistics summary:":
                alignments.append((query_seq, target_seq))
                query_seq = target_seq = ""
            elif query_seq:
                # New block of domain
                block = []
                while line or len(block) < 4:
                    block.append(line)
                    line = next(fh).strip()

                del block[:-4]
                target_seq += block[0].split()[2]
                query_seq += block[2].split()[2]

    return alignments