# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
"""utils"""

import os
import os.path as osp
import sys
import numpy as np
import mindspore.dataset as ds


def gen_idx(train_color_label, train_thermal_label):
    """
    Generate
    """
    color_pos = []
    unique_label_color = np.unique(train_color_label)
    for i in range(len(unique_label_color)):
        tmp_pos = [k for k, v in enumerate(train_color_label) if v == unique_label_color[i]]
        color_pos.append(tmp_pos)

    thermal_pos = []
    unique_label_thermal = np.unique(train_thermal_label)
    for i in range(len(unique_label_thermal)):
        tmp_pos = [k for k, v in enumerate(train_thermal_label) if v == unique_label_thermal[i]]
        thermal_pos.append(tmp_pos)

    return color_pos, thermal_pos


class IdentitySampler(ds.Sampler):
    """Sample person identities evenly in each batch.
        Args:
            train_color_label, train_thermal_label: labels of two modalities
            color_pos, thermal_pos: positions of each identity
            batchsize: batch size
    """

    def __init__(self, train_color_label, train_thermal_label, color_pos, thermal_pos, num_pos, batchsize):
        super(IdentitySampler, self).__init__()
        # np.random.seed(0)
        uni_label = np.unique(train_color_label)
        self.n_classes = len(uni_label)
        n = np.maximum(len(train_color_label), len(train_thermal_label))
        index1 = index2 = None
        for j in range(int(n / (batchsize * num_pos)) + 1):
            batch_idx = np.random.choice(uni_label, batchsize, replace=False)
            for i in range(batchsize):
                sample_color = np.random.choice(color_pos[batch_idx[i]], num_pos)
                sample_thermal = np.random.choice(thermal_pos[batch_idx[i]], num_pos)

                if j == 0 and i == 0:
                    index1 = sample_color
                    index2 = sample_thermal
                # else:
                #     index1 = np.hstack((index1, sample_color))
                #     index2 = np.hstack((index2, sample_thermal))
                #
        self.index1 = index1
        self.index2 = index2
        self.n = n
        self.num_samples = n

    def __iter__(self):
        # return iter(np.arange(len(self.index1)))
        for i in range(len(self.index1)):
            yield i

    def __len__(self):
        return self.n


class AverageMeter:
    """Computers and stores the average & current value"""

    def __init__(self):
        self.reset()

    def reset(self):
        self.val = 0
        self.avg = 0
        self.sum = 0
        self.count = 0

    def update(self, val, n=1):
        self.val = val
        self.sum += val * n
        self.count += n
        self.avg = self.sum / self.count


def mkdir_if_missing(directory):
    """mkdir_if_missing"""
    if not osp.exists(directory):
        try:
            os.makedirs(directory)
        except OSError as e:
            print(e)


class Logger:
    """
    Write console output to external text file.
    Code imported from https://github.com/Cysu/open-reid/blob/master/reid/utils/logging.py.
    """

    def __init__(self, fpath=None):
        self.console = sys.stdout
        self.file = None
        if fpath is not None:
            mkdir_if_missing(osp.dirname(fpath))
            self.file = open(fpath, 'w')

    def __del__(self):
        self.close()

    def __enter__(self):
        pass

    def __exit__(self, *args):
        self.close()

    def write(self, msg):
        self.console.write(msg)
        if self.file is not None:
            self.file.write(msg)

    def flush(self):
        self.console.flush()
        if self.file is not None:
            self.file.flush()
            os.fsync(self.file.fileno())

    def close(self):
        self.console.close()
        if self.file is not None:
            self.file.close()

# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
"""utils"""

import os
import os.path as osp
import sys
import numpy as np
import mindspore.dataset as ds


def gen_idx(train_color_label, train_thermal_label):
    """
    Generate
    """
    color_pos = []
    unique_label_color = np.unique(train_color_label)
    for i in range(len(unique_label_color)):
        tmp_pos = [k for k, v in enumerate(train_color_label) if v == unique_label_color[i]]
        color_pos.append(tmp_pos)

    thermal_pos = []
    unique_label_thermal = np.unique(train_thermal_label)
    for i in range(len(unique_label_thermal)):
        tmp_pos = [k for k, v in enumerate(train_thermal_label) if v == unique_label_thermal[i]]
        thermal_pos.append(tmp_pos)

    return color_pos, thermal_pos


class IdentitySampler(ds.Sampler):
    """Sample person identities evenly in each batch.
        Args:
            train_color_label, train_thermal_label: labels of two modalities
            color_pos, thermal_pos: positions of each identity
            batchsize: batch size
    """

    def __init__(self, train_color_label, train_thermal_label, color_pos, thermal_pos, num_pos, batchsize):
        super(IdentitySampler, self).__init__()
        # np.random.seed(0)
        uni_label = np.unique(train_color_label)
        self.n_classes = len(uni_label)
        n = np.maximum(len(train_color_label), len(train_thermal_label))
        index1 = index2 = None
        for j in range(int(n / (batchsize * num_pos)) + 1):
            batch_idx = np.random.choice(uni_label, batchsize, replace=False)
            for i in range(batchsize):
                sample_color = np.random.choice(color_pos[batch_idx[i]], num_pos)
                sample_thermal = np.random.choice(thermal_pos[batch_idx[i]], num_pos)

                if j == 0 and i == 0:
                    index1 = sample_color
                    index2 = sample_thermal
                # else:
                #     index1 = np.hstack((index1, sample_color))
                #     index2 = np.hstack((index2, sample_thermal))
                #
        self.index1 = index1
        self.index2 = index2
        self.n = n
        self.num_samples = n

    def __iter__(self):
        # return iter(np.arange(len(self.index1)))
        for i in range(len(self.index1)):
            yield i

    def __len__(self):
        return self.n


class AverageMeter:
    """Computers and stores the average & current value"""

    def __init__(self):
        self.reset()

    def reset(self):
        self.val = 0
        self.avg = 0
        self.sum = 0
        self.count = 0

    def update(self, val, n=1):
        self.val = val
        self.sum += val * n
        self.count += n
        self.avg = self.sum / self.count


def mkdir_if_missing(directory):
    """mkdir_if_missing"""
    if not osp.exists(directory):
        try:
            os.makedirs(directory)
        except OSError as e:
            print(e)


class Logger:
    """
    Write console output to external text file.
    Code imported from https://github.com/Cysu/open-reid/blob/master/reid/utils/logging.py.
    """

    def __init__(self, fpath=None):
        self.console = sys.stdout
        self.file = None
        if fpath is not None:
            mkdir_if_missing(osp.dirname(fpath))
            self.file = open(fpath, 'w')

    def __del__(self):
        self.close()

    def __enter__(self):
        pass

    def __exit__(self, *args):
        self.close()

    def write(self, msg):
        self.console.write(msg)
        if self.file is not None:
            self.file.write(msg)

    def flush(self):
        self.console.flush()
        if self.file is not None:
            self.file.flush()
            os.fsync(self.file.fileno())

    def close(self):
        self.console.close()
        if self.file is not None:
            self.file.close()

# Copyright 2021 Huawei Technologies Co., Ltd # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================ utils Generate Sample person identities evenly in each batch.         Args:             train_color_label, train_thermal_label: labels of two modalities             color_pos, thermal_pos: positions of each identity             batchsize: batch size # np.random.seed(0) # else: #     index1 = np.hstack((index1, sample_color)) #     index2 = np.hstack((index2, sample_thermal)) # # return iter(np.arange(len(self.index1))) Computers and stores the average & current value mkdir_if_missing Write console output to external text file.     Code imported from https://github.com/Cysu/open-reid/blob/master/reid/utils/logging.py.