# Path: guacamol/distribution_learning_benchmark.py
# class DistributionLearningBenchmark:
#     """
#     Base class for assessing how well a model is able to generate molecules matching a molecule distribution.
# 
#     Derived class should implement the assess_molecules function
#     """
# 
#     def __init__(self, name: str, number_samples: int) -> None:
#         self.name = name
#         self.number_samples = number_samples
# 
#     @abstractmethod
#     def assess_model(self, model: DistributionMatchingGenerator) -> DistributionLearningBenchmarkResult:
#         """
#         Assess a distribution-matching generator model.
# 
#         Args:
#             model: model to assess
#         """
# 
# class DistributionLearningBenchmarkResult:
#     """
#     Contains the results of a distribution learning benchmark.
# 
#     NB: timing does not make sense since training happens outside of DistributionLearningBenchmark.
#     """
# 
#     def __init__(self, benchmark_name: str, score: float, sampling_time: float, metadata: Dict[str, Any]) -> None:
#         """
#         Args:
#             benchmark_name: name of the distribution-learning benchmark
#             score: benchmark score
#             sampling_time: time for sampling the molecules in seconds
#             metadata: benchmark-specific information
#         """
#         self.benchmark_name = benchmark_name
#         self.score = score
#         self.sampling_time = sampling_time
#         self.metadata = metadata
# 
# Path: guacamol/distribution_matching_generator.py
# class DistributionMatchingGenerator(metaclass=ABCMeta):
#     """
#     Interface for molecule generators.
#     """
# 
#     @abstractmethod
#     def generate(self, number_samples: int) -> List[str]:
#         """
#         Samples SMILES strings from a molecule generator.
# 
#         Args:
#             number_samples: number of molecules to generate
# 
#         Returns:
#             A list of SMILES strings.
#         """
# 
# Path: guacamol/benchmark_suites.py
# def distribution_learning_benchmark_suite(chembl_file_path: str,
#                                           version_name: str,
#                                           number_samples: int) -> List[DistributionLearningBenchmark]:
#     """
#     Returns a suite of benchmarks for a specified benchmark version
# 
#     Args:
#         chembl_file_path: path to ChEMBL training set, necessary for some benchmarks
#         version_name: benchmark version
# 
#     Returns:
#         List of benchmaks
#     """
# 
#     # For distribution-learning, v1 and v2 are identical
#     if version_name == 'v1' or version_name == 'v2':
#         return distribution_learning_suite_v1(chembl_file_path=chembl_file_path, number_samples=number_samples)
# 
#     raise Exception(f'Distribution-learning benchmark suite "{version_name}" does not exist.')
# 
# Path: guacamol/utils/data.py
# def get_time_string():
#     lt = time.localtime()
#     return "%04d%02d%02d-%02d%02d" % (lt.tm_year, lt.tm_mon, lt.tm_mday, lt.tm_hour, lt.tm_min)


import datetime
import json
import logging
import guacamol
from collections import OrderedDict
from typing import List, Dict, Any
from guacamol.distribution_learning_benchmark import DistributionLearningBenchmark, DistributionLearningBenchmarkResult
from guacamol.distribution_matching_generator import DistributionMatchingGenerator
from guacamol.benchmark_suites import distribution_learning_benchmark_suite
from guacamol.utils.data import get_time_string


logger = logging.getLogger(__name__)
logger.addHandler(logging.NullHandler())


def assess_distribution_learning(model: DistributionMatchingGenerator,
                                 chembl_training_file: str,
                                 json_output_file='output_distribution_learning.json',
                                 benchmark_version='v1') -> None:
    """
    Assesses a distribution-matching model for de novo molecule design.

    Args:
        model: Model to evaluate
        chembl_training_file: path to ChEMBL training set, necessary for some benchmarks
        json_output_file: Name of the file where to save the results in JSON format
        benchmark_version: which benchmark suite to execute
    """
    _assess_distribution_learning(model=model,
                                  chembl_training_file=chembl_training_file,
                                  json_output_file=json_output_file,
                                  benchmark_version=benchmark_version,
                                  number_samples=10000)



# Path: guacamol/distribution_learning_benchmark.py
# class DistributionLearningBenchmark:
#     """
#     Base class for assessing how well a model is able to generate molecules matching a molecule distribution.
# 
#     Derived class should implement the assess_molecules function
#     """
# 
#     def __init__(self, name: str, number_samples: int) -> None:
#         self.name = name
#         self.number_samples = number_samples
# 
#     @abstractmethod
#     def assess_model(self, model: DistributionMatchingGenerator) -> DistributionLearningBenchmarkResult:
#         """
#         Assess a distribution-matching generator model.
# 
#         Args:
#             model: model to assess
#         """
# 
# class DistributionLearningBenchmarkResult:
#     """
#     Contains the results of a distribution learning benchmark.
# 
#     NB: timing does not make sense since training happens outside of DistributionLearningBenchmark.
#     """
# 
#     def __init__(self, benchmark_name: str, score: float, sampling_time: float, metadata: Dict[str, Any]) -> None:
#         """
#         Args:
#             benchmark_name: name of the distribution-learning benchmark
#             score: benchmark score
#             sampling_time: time for sampling the molecules in seconds
#             metadata: benchmark-specific information
#         """
#         self.benchmark_name = benchmark_name
#         self.score = score
#         self.sampling_time = sampling_time
#         self.metadata = metadata
# 
# Path: guacamol/distribution_matching_generator.py
# class DistributionMatchingGenerator(metaclass=ABCMeta):
#     """
#     Interface for molecule generators.
#     """
# 
#     @abstractmethod
#     def generate(self, number_samples: int) -> List[str]:
#         """
#         Samples SMILES strings from a molecule generator.
# 
#         Args:
#             number_samples: number of molecules to generate
# 
#         Returns:
#             A list of SMILES strings.
#         """
# 
# Path: guacamol/benchmark_suites.py
# def distribution_learning_benchmark_suite(chembl_file_path: str,
#                                           version_name: str,
#                                           number_samples: int) -> List[DistributionLearningBenchmark]:
#     """
#     Returns a suite of benchmarks for a specified benchmark version
# 
#     Args:
#         chembl_file_path: path to ChEMBL training set, necessary for some benchmarks
#         version_name: benchmark version
# 
#     Returns:
#         List of benchmaks
#     """
# 
#     # For distribution-learning, v1 and v2 are identical
#     if version_name == 'v1' or version_name == 'v2':
#         return distribution_learning_suite_v1(chembl_file_path=chembl_file_path, number_samples=number_samples)
# 
#     raise Exception(f'Distribution-learning benchmark suite "{version_name}" does not exist.')
# 
# Path: guacamol/utils/data.py
# def get_time_string():
#     lt = time.localtime()
#     return "%04d%02d%02d-%02d%02d" % (lt.tm_year, lt.tm_mon, lt.tm_mday, lt.tm_hour, lt.tm_min)


# Path: guacamol/assess_distribution_learning.py
import datetime
import json
import logging
import guacamol
from collections import OrderedDict
from typing import List, Dict, Any
from guacamol.distribution_learning_benchmark import DistributionLearningBenchmark, DistributionLearningBenchmarkResult
from guacamol.distribution_matching_generator import DistributionMatchingGenerator
from guacamol.benchmark_suites import distribution_learning_benchmark_suite
from guacamol.utils.data import get_time_string



logger = logging.getLogger(__name__)
logger.addHandler(logging.NullHandler())


def assess_distribution_learning(model: DistributionMatchingGenerator,
                                 chembl_training_file: str,
                                 json_output_file='output_distribution_learning.json',
                                 benchmark_version='v1') -> None:
    """
    Assesses a distribution-matching model for de novo molecule design.

    Args:
        model: Model to evaluate
        chembl_training_file: path to ChEMBL training set, necessary for some benchmarks
        json_output_file: Name of the file where to save the results in JSON format
        benchmark_version: which benchmark suite to execute
    """
    _assess_distribution_learning(model=model,
                                  chembl_training_file=chembl_training_file,
                                  json_output_file=json_output_file,
                                  benchmark_version=benchmark_version,
                                  number_samples=10000)



def _assess_distribution_learning(model: DistributionMatchingGenerator,