from dnv_bladed_results import ResultsApi, Run, UsageExamples
import dnv_bladed_results as dnvres
import numpy as np
import os

############   Bladed Results API: Find runs   ############

# Demonstrates how to find runs starting in a root folder and applying filters


def run_script():
    r"""
    Example script that runs when this Python module is called as the main function.
    
    - Finds runs starting in a root folder using various search criteria:
    
      - runs filtered on completion state and calculation type
      - runs matching name
      - runs matching name regex.
    """

    runs_root_folder = os.path.join(UsageExamples.__path__[0], "Runs")
    from datetime import datetime
    start_time = datetime.now()
    find_runs_with_filter_criteria(runs_root_folder)
    end_time = datetime.now()
    total_time = end_time - start_time
    print(f"\nTime taken (s) = {total_time.total_seconds()}\n")

    # Clear the cache
    ResultsApi.clear_runs()


def display_runs(description, runs: np.ndarray[Run]):
    print(f"\nShowing {description} ({runs.size} found):")
    run: Run
    for run in runs:
        print(run.directory + run.name)


def find_runs_with_filter_criteria(root_folder):

    # Find all unsuccessful runs
    ResultsApi.SearchSettings.completion_state_filter = dnvres.COMPLETION_STATE_UNSUCCESSFUL_RUNS_ONLY
    unsuccessful_runs = ResultsApi.get_runs(root_folder)
    display_runs("runs that did not succeed", unsuccessful_runs)
    ResultsApi.SearchSettings.completion_state_filter = dnvres.COMPLETION_STATE_ALL_COMPLETION_STATES

    # Find all turbine simulation runs
    ResultsApi.SearchSettings.calculation_type_filter = dnvres.CALCULATION_TYPE_ALL_TURBINE_SIMULATIONS
    turbine_simulation_runs = ResultsApi.get_runs(root_folder)
    display_runs("turbine simulation runs", turbine_simulation_runs)
    ResultsApi.SearchSettings.calculation_type_filter = dnvres.CALCULATION_TYPE_ALL_CALCULATION_TYPES

    # Find all post-processing runs
    ResultsApi.SearchSettings.calculation_type_filter = dnvres.CALCULATION_TYPE_ALL_POST_PROCESSING_CALCULATIONS
    post_processing_runs = ResultsApi.get_runs(root_folder)
    display_runs("post-processing runs", post_processing_runs)
    ResultsApi.SearchSettings.calculation_type_filter = dnvres.CALCULATION_TYPE_ALL_CALCULATION_TYPES

    # Find runs matching a name - case insensitive by default
    runs_named_powprod = ResultsApi.get_runs_matching_name(root_folder, "powprod")
    display_runs("runs named 'powprod'", runs_named_powprod)
    
    # Find runs with name matching regular expression
    runs_with_number_in_name = ResultsApi.get_runs_matching_name_regex(root_folder, r".*\d+.*")
    display_runs("runs with name containing a number", runs_with_number_in_name)

    runs_with_name_starting_with_p = ResultsApi.get_runs_matching_name_regex(root_folder, "p.*")
    display_runs("runs with name beginning wih letter 'p'", runs_with_name_starting_with_p)


def find_runs_stress_test(root_folder):

    # Find runs and display count
    ResultsApi.CacheSettings.run_caching_enabled = False
    all_runs = ResultsApi.get_runs(root_folder, SEARCH_SCOPE_RECURSIVE_SEARCH)    
    print(f"Found {all_runs.size} runs staring in root folder\n")


if __name__ == "__main__":
    run_script()
