import itertools


def get_deletion_effects(deletion_record, gff_db, regulatory_margin=2000):
    """
    Figure out the effects of a deletion using a gff.

    Args:
        deletion_record (vcf.Record): a vcf Record representing the
            deletion
        gff_db (gffutils.FeatureDB): a gffutils DB of a genome's
            annotations
        regulatory_margin (int): the amount of sequence on either side
            of the deletion to look in for genes to be classified as
            having their regulatory regions affected
    """
    affected_genes = set()
    intergenic = True
    regulatory, intronic, coding = [False] * 3

    # first, go through all the features that overlap the deletion
    # and use them to set the above booleans and add any affected
    # genes to affected_genes
    features_in_deletion = gff_db.region(
        seqid=deletion_record.CHROM,
        start=deletion_record.POS,
        end=deletion_record.sv_end,
    )
    for feature in features_in_deletion:
        if feature.featuretype == "gene":
            affected_genes.add(feature.attributes["Name"][0].upper())
            intergenic = False
            intronic = True
        elif feature.featuretype == "CDS":
            coding = True
            intronic = False

    # next, look for any genes *near* the deletion
    features_near_deletion = itertools.chain(
        gff_db.region(
            seqid=deletion_record.CHROM,
            start=deletion_record.POS - regulatory_margin,
            end=deletion_record.POS,
        ),
        gff_db.region(
            seqid=deletion_record.CHROM,
            start=deletion_record.sv_end,
            end=deletion_record.sv_end + regulatory_margin,
        ),
    )
    for feature in features_near_deletion:
        if feature.featuretype == "gene":
            gene_name = feature.attributes["Name"][0].upper()
            # only consider this a deletion of a regulatory region if
            # this gene has not been otherwise affected
            if gene_name not in affected_genes:
                regulatory = True
                intergenic = False
                affected_genes.add(gene_name)

    return affected_genes, intergenic, regulatory, intronic, coding