# Copyright (c) Open-MMLab. All rights reserved.
import os.path as osp
import numpy as np
import os
from mmcv.utils import TORCH_VERSION
from mmcv.runner.dist_utils import master_only
from mmcv.runner import TensorboardLoggerHook, HOOKS
import time


@HOOKS.register_module()
class MyTensorboardLoggerHook(TensorboardLoggerHook):

    def __init__(self,
                 log_dir=None,
                 interval=10,
                 ignore_last=True,
                 reset_flag=False,
                 by_epoch=True):
        super(MyTensorboardLoggerHook, self).__init__(interval, ignore_last,
                                                      reset_flag, by_epoch)
        self.log_dir = log_dir

    @master_only
    def before_run(self, runner):
        super(MyTensorboardLoggerHook, self).before_run(runner)
        if TORCH_VERSION < '1.1' or TORCH_VERSION == 'parrots':
            try:
                from tensorboardX import SummaryWriter
            except ImportError:
                raise ImportError('Please install tensorboardX to use '
                                  'MyTensorboardLoggerHook.')
        else:
            try:
                from torch.utils.tensorboard import SummaryWriter
            except ImportError:
                raise ImportError(
                    'Please run "pip install future tensorboard" to install '
                    'the dependencies to use torch.utils.tensorboard '
                    '(applicable to PyTorch 1.1 or higher)')
        self.SummaryWriter = SummaryWriter
        if self.log_dir is None:
            self.log_dir = osp.join(runner.work_dir, 'tf_logs')
        # self.writer = SummaryWriter(self.log_dir)

        # tags = self.get_loggable_tags(runner, allow_text=True)
        self.writers = dict()
        # for tag in tags.keys():
        #     if tag not in self.writers:
        #         self.writers[tag] = SummaryWriter(osp.join(self.log_dir, tag))

    @master_only
    def log(self, runner):
        tags = self.get_loggable_tags(runner, allow_text=True)
        for tag, val in tags.items():
            tag = tag.replace('/', '_')
            if not tag in self.writers:
                writer = self.SummaryWriter(osp.join(self.log_dir, str(tag)))
                self.writers[tag] = writer
                # print(f'tag {tag} not in writers {self.writers}')
                # continue
            writer = self.writers[tag]

            if isinstance(val, str):
                # writer.add_text(tag, val, self.get_iter(runner))
                pass
            else:
                writer.add_scalar(tag, val, self.get_iter(runner))
                # add events.bin
                path = osp.join(self.log_dir, str(
                    tag), 'data', "events.bin")
                value = [self.get_iter(runner), val, float(time.time())]
                if osp.exists(path):
                    save_data = np.fromfile(path, dtype=np.float)
                else:
                    os.makedirs(osp.dirname(path), exist_ok=True)
                    save_data = np.array([])
                save_data = np.insert(save_data, len(save_data), value)
                save_data.tofile(path)

    @master_only
    def after_run(self, runner):
        for writer in self.writers.values():
            writer.close()
