import logging
import os

from multiqc.base_module import ModuleNoSamplesFound
from .base_metrics import DragenBaseMetrics
from .content_metrics import DragenContentMetrics
from .gc_metrics import DragenFastqcGcMetrics
from .read_metrics import DragenReadMetrics
from .util import parse_fastqc_metrics_file

log = logging.getLogger(__name__)


class MultiqcModule(DragenBaseMetrics, DragenReadMetrics, DragenFastqcGcMetrics, DragenContentMetrics):
    """
    DRAGEN has a number of different pipelines and outputs, including base calling, DNA and RNA alignment, and
    many others. Starting with the release of DRAGEN v3.6, it also supports primary analysis of sequencing
    data, modelled after the QC metrics generated by the widely used FastQC tool.

    This module parses the output from that hardware-accelerated QC tool, and uses it to generate similar
    plots to both FastQC and MultiQC's current FastQC module. These plots are presented in their own
    section and module, such that they can be run indepedently or in conjunction with other MultiQC
    DRAGEN modules as desired.

    - `<output prefix>.fastqc_metrics.csv`
      - Pre-calculated positional QV quantiles
      - Mean QVs by read position and base
      - A histogram of estimated read-level qualities
      - A histogram of read lengths
      - A smoothed histogram of sample GC content
      - Average read quality values for each GC content bin
      - Positional prevalence of ambiguous bases
      - Positional base content
      - Adapter/Kmer sequence start positions

    #### Quality score box plots

    By default, the box plots showing the range of quality scores are only shown if there are maximum 2 samples in the report. You can change this threshold with the following MultiQC config (eg. to max 10 samples):

    ```yaml
    dragen_fastqc:
      quality_range_boxplots_max_samples: 10
    ```

    If you prefer, you can force MultiQC to generate these box plots for _all_ samples using the following configuration:

    ```yaml
    dragen_fastqc:
      force_quality_range_boxplots: true
    ```
    """

    def __init__(self):
        super(MultiqcModule, self).__init__(
            name="DRAGEN-FastQC",
            anchor="dragen-fastqc",
            href="https://www.illumina.com/products/by-type/informatics-products/dragen-bio-it-platform.html",
            info="Illumina Bio-IT Platform that uses FPGA for secondary analysis of sequencing data",
            # Can't find a DOI // doi=
        )

        self.css = {
            "assets/css/multiqc_fastqc.css": os.path.join(
                os.path.dirname(__file__), "..", "fastqc", "assets", "css", "multiqc_fastqc.css"
            )
        }
        self.js = {
            "assets/js/multiqc_dragen_fastqc.js": os.path.join(
                os.path.dirname(__file__), "assets", "js", "multiqc_dragen_fastqc.js"
            )
        }
        self.intro += '<script type="application/json" class="fastqc_passfails">["dragen_fastqc", {"per_base_sequence_content": {"TEST": "pass"}}]</script>'

        data_by_sample = {}
        for f in self.find_log_files("dragen_fastqc"):
            s_name, data_by_mate = parse_fastqc_metrics_file(f)

            # Clean sample name and key
            new_s_name = self.clean_s_name(s_name, f)
            data_by_mate[new_s_name] = data_by_mate.pop(s_name)
            s_name = new_s_name
            del new_s_name

            if s_name in data_by_sample:
                log.debug(f"Duplicate sample name found! Overwriting: {f['s_name']}")
            self.add_data_source(f, s_name)
            data_by_sample.update(data_by_mate)

            # Superfluous function call to confirm that it is used in this module
            # Replace None with actual version if it is available
            self.add_software_version(None, s_name)

        # Filter to strip out ignored sample names:
        self.dragen_fastqc_data = self.ignore_samples(data_by_sample)

        # TODO: Split this up and write the interesting bits to files
        # Currently is 13760 lines in my test, which is too much.
        # self.write_data_file(self.dragen_fastqc_data, "dragen_fastqc")

        samples_found = set()

        # "POSITIONAL QUALITY" and "POSITIONAL BASE MEAN QUALITY" metrics
        samples_found |= self.add_base_metrics()

        # "READ MEAN QUALITY" and "READ LENGTHS" metrics
        samples_found |= self.add_read_metrics()

        # "GC CONTENT" and "GC CONTENT QUALITY" metrics
        samples_found |= self.add_gc_metrics()

        # "POSITIONAL BASE CONTENT" metrics
        samples_found |= self.add_content_metrics()

        if len(samples_found) == 0:
            raise ModuleNoSamplesFound
        log.info(f"Found {len(samples_found)} reports")
