import random
from locust import HttpUser, task, between, events
from locust.exception import StopUser


@events.init_command_line_parser.add_listener
def _(parser):
    parser.add_argument("--token",
                        type=str,
                        env_var="LOCUST_MY_ARGUMENT",
                        is_secret=True,
                        help=":8080/token",
                        default="")


class StudentActor(HttpUser):
    wait_time = between(.250, .500)
    weight = 1

    course_id = None
    lecture_id = None
    id = None
    header = None

    def on_start(self):
        self.header = {'Authorization': f'Bearer {self.environment.parsed_options.token}'}

        response = self.client.post(
            url='/users',
            auth=None,
            headers=self.header,
            json={
                "username": "xnocni",
                "email": f"xnocni{random.randint(0, 42069)}@mail.muni.cz",
                "firstName": "Hana",
                "lastName": "Sykorova"
            },
            name="Add User"
        )
        if response.status_code == 201:
            self.id = response.json()["id"]
        return super().on_start()

    @task(3)
    def get_courses_english(self):
        response = self.client.get(
            url='/courses/findAllByLang?lang=ENGLISH',
            auth=None,
            headers=self.header,
            name="Find Courses"
        )
        if response.status_code == 200:
            json = response.json()
            if len(json) > 0:
                self.course_id = json[0]["id"]

    @task
    def enrol_course(self):
        if self.course_id is None or self.id is None:
            return
        self.client.patch(
            url=f'/courses/enrolStudent/{self.course_id}?studentId={self.id}',
            auth=None,
            headers=self.header,
            name="Enrol Courses"
        )

    @task
    def get_lectures_by_course(self):
        if self.course_id is None:
            return
        response = self.client.get(
            url=f'/lectures/findByCourse?courseId={self.course_id}',
            auth=None,
            headers=self.header,
            name="Find Lectures"
        )
        if response.status_code == 200:
            json = response.json()
            if len(json) > 0:
                self.lecture_id = json[0]["id"]

    @task
    def enrol_lecture(self):
        if self.lecture_id is None or self.id is None:
            return
        self.client.patch(
            url=f'/lectures/enrolStudent/{self.lecture_id}?studentId={self.id}',
            auth=None,
            headers=self.header,
            name="Enrol Lectures"
        )


class LecturerActor(HttpUser):
    weight = 0
    fixed_count = 1
    wait_time = between(.100, .900)

    courses_created = 0
    lecture_created = 0
    course_ids = set()
    id = None
    header = None

    def on_start(self):
        self.header = {'Authorization': f'Bearer {self.environment.parsed_options.token}'}

        response = self.client.post(
            url='/users',
            auth=None,
            headers=self.header,
            json={
                "username": "xhana",
                "email": f"xhana{random.randint(0, 42069)}@mail.muni.cz",
                "firstName": "Hana",
                "lastName": "Sykorova"
            },
            name="Add User"
        )
        if response.status_code == 201:
            self.id = response.json()["id"]
        return super().on_start()

    @task
    def new_course(self):
        if self.courses_created < 3:
            response = self.client.post(
                url="/courses",
                auth=None,
                headers=self.header,
                name="Create Course",
                json={
                    "name": "string",
                    "capacity": 10,
                    "language": random.choice(["SPANISH", "ENGLISH"]),
                    "proficiency": random.choice(["A1", "B1", "C1"])
                }
            )
            if response.status_code == 201:
                self.course_ids.add(response.json()['id'])
                self.courses_created += 1

    @task
    def new_lecture(self):
        if self.courses_created > 0 and self.lecture_created < 10:
            response = self.client.post(
                url="/lectures",
                auth=None,
                headers=self.header,
                name="Create Lecture",
                json={
                    "lectureFrom": "2024-04-26T18:06:30.658Z",
                    "lectureTo": "2024-04-27T18:06:30.658Z",
                    "topic": "string",
                    "capacity": random.choice([10, 20, 30]),
                    "courseId": random.choice(list(self.course_ids))
                }
            )
            if response.status_code == 201:
                self.lecture_created += 1
        if self.lecture_created >= 20:
            raise StopUser()
