import logging
from typing import Counter


def supported(aln):
    """Get only the supported consensus residues in each column.

    Meaning:
    - Omit majority-gap columns
    - Omit columns where no residue type appears more than once
    - In case of a tie, return all the top-scoring residue types
      (no prioritization)

    Returns a *list* -- not a string! -- where elements are strings of the
    consensus character(s), potentially a gap ('-') or multiple chars ('KR').
    """
    def col_consensus(columns):
        """Calculate the consensus chars for an iterable of columns."""
        for col in columns:
            if (# Majority gap chars
                (col.count('-') >= len(col)/2) or
                # Lowercase cols mean "don't include in consensus"
                all(c.islower() for c in col if c not in '.-')
                ):
                yield '-'
                continue
            # Validation - copied from consensus() above
            if any(c.islower() for c in col):
                logging.warn('Mixed lowercase and uppercase letters in a '
                        'column: ' + ''.join(col))
                col = map(str.upper, col)
            # Calculate the consensus character
            most_common = Counter(
                    [c for c in col if c not in '-']
                    ).most_common()
            if not most_common:
                # XXX ever reached?
                logging.warn("Column is all gaps! How did that happen?")
            if most_common[0][1] == 1:
                # No char has frequency > 1; no consensus char
                yield '-'
            elif (len(most_common) > 1 and
                    most_common[0][1] == most_common[1][1]):
                # Tie for most-common residue type
                ties = [x[0] for x in most_common
                        if x[1] == most_common[0][1]]
                yield ''.join(ties)
            else:
                yield most_common[0][0]

    return list(col_consensus(zip(*aln)))