"""Benchmark."""

# Copyright (c) 2020-2021 Thomas Paviot (tpaviot@gmail.com)
#
# This file is part of ProcessScheduler.
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.

import os
import random
from resource import getrusage, RUSAGE_SELF
import processscheduler as ps

def _get_big_random_problem(name:str, n: int) -> ps.SchedulingProblem:
    """ returns a problem with n tasks and n * 3 workers. Workers are random assigned. """
    problem = ps.SchedulingProblem(name)

    tasks = [ps.FixedDurationTask('task%i' % i,
                                  duration=random.randint(1, n // 10)) for i in range(n)]

    workers = [ps.Worker('task%i' % i) for i in range(n * 4)]

    # for each task, add three single required workers
    for task in tasks:
        random_workers = random.sample(workers, 8)  # all different
        task.add_required_resources(random_workers[:5])
        # also add two SelectWorkers
        task.add_required_resource(ps.SelectWorkers(random.sample(workers[-3:], 1)))

    return problem

pb = _get_big_random_problem('benchmark', 300)
solver = ps.SchedulingSolver(pb, verbosity=False, parallel=True)
solution = solver.solve()

# generate log
log = ""
log += "%s"%solver._solver.statistics()
print(getrusage(RUSAGE_SELF))

# memory usage using memory profiler
from memory_profiler import profile
@profile
def solve_pb():
    solver = ps.SchedulingSolver(pb, verbosity=False, parallel=False)
    solution = solver.solve()
solve_pb()

@profile
def solve_pb_with_optim():
    pb.add_objective_makespan()
    solver = ps.SchedulingSolver(pb, verbosity=False, parallel=False)
    solution = solver.solve()
solve_pb_with_optim()

print(log)
