import os
import subprocess
import sys
from ..utils.utils import *

# Copyright (c) Efabless Corporation. All rights reserved.
# See LICENSE file in the project root for full license information.


class Report:
    def __init__(self, design, tag, params):
        self.design = design
        self.tag = tag
        self.current_directory = os.path.dirname(__file__)
        self.report_script = os.path.join(self.current_directory, 'report.sh')
        self.report_command = '{script} {path}'.format(
                script=self.report_script,
                path=get_run_path(design=design, tag=tag)
            )
        self.configuration = params
        self.raw_report = None
        self.formatted_report = None

    values = ['design', 'config', 'runtime', 'cell_count', 'violations', 'wire_length', 'vias', 'wns', 'HPWL',
            'wire_bits', 'public_wire_bits', 'cells_pre_abc', 'DFF', 'XOR', 'XNOR', 'MUX',
            'inputs', 'outputs', 'level']
        

    @classmethod
    def get_header(cls):
        header = ','.join(cls.values)
        return header


    def run_script(self):
        return subprocess.check_output(self.report_command.split()).decode(sys.getfilesystemencoding())

    def format_report(self):
        splited_report = self.raw_report.split()
        report = ",".join(splited_report)
        report = "{design},{tag},".format(
                design=self.design,
                tag=self.tag
                ) + report + "," + ",".join(self.configuration)

        return report


    def get_report(self):
        self.raw_report = self.run_script()
        self.formatted_report = self.format_report()

        return self.formatted_report


if __name__ == '__main__':
    report = Report('test_design', 'test_tag', 'test_config')
    print(Report.get_header())
