import kfp
from kfp import dsl
from kfp.components import func_to_container_op

# ==============================================================================
# 재학습 트리거 및 조건부 실행 파이프라인 실습 코드
#
# 본 예제는 Kubeflow Pipelines(KFP)를 사용하여 간단한 ML 파이프라인을 구축하고,
# 특정 조건(모델 정확도)에 따라 다음 컴포넌트의 실행 여부를 결정하는 방법을 보여줍니다.
#
# 실제 프로덕션 환경에서는 데이터 변경, 모델 성능 저하 등을 감지하는 모니터링 시스템이
# 이 파이프라인을 주기적으로 또는 이벤트 기반으로 '트리거'하여 모델을 '재학습'하고,
# 성능이 개선되었을 경우에만 자동으로 배포하는 흐름을 자동화할 수 있습니다.
# ==============================================================================


# Component 1: 데이터 전처리 및 모델 학습
# 실제로는 데이터를 불러와 전처리하고 모델을 학습시키는 복잡한 과정이 포함됩니다.
# 여기서는 간단히 학습된 모델의 '정확도'를 반환하는 것으로 시뮬레이션합니다.
@func_to_container_op
def train_model(learning_rate: float) -> float:
    """간단한 모델을 학습하고 정확도를 반환하는 컴포넌트."""
    print(f"모델 학습 시작... (learning_rate: {learning_rate})")
    # 임의의 모델 정확도 반환 (실제로는 평가 데이터셋으로 측정)
    accuracy = 0.95
    print(f"모델 학습 완료. 정확도: {accuracy}")
    return accuracy


# Component 2: 모델 배포
# 실제로는 학습된 모델을 서빙 환경에 배포하는 과정입니다.
# 여기서는 간단히 배포 메시지를 출력합니다.
@func_to_container_op
def deploy_model(accuracy: float):
    """(시뮬레이션) 학습된 모델을 프로덕션에 배포하는 컴포넌트."""
    print(f"배포 시작... 성능 임계값 통과 (정확도: {accuracy})")
    print("모델이 성공적으로 배포되었습니다.")


# Pipeline: 전체 ML 워크플로우를 정의합니다.
@dsl.pipeline(
    name="Conditional Execution Pipeline",
    description="모델 정확도에 따라 배포 여부를 결정하는 파이프라인",
)
def conditional_pipeline(learning_rate: float = 0.01, deploy_threshold: float = 0.9):
    """
    ML 파이프라인 정의:
    1. 모델을 학습시킵니다.
    2. 학습된 모델의 정확도가 임계값(deploy_threshold)보다 높을 경우에만 배포를 진행합니다.
    """
    # 1. 모델 학습 컴포넌트 실행
    train_task = train_model(learning_rate=learning_rate)

    # 2. 조건부 실행: 학습된 모델의 정확도(train_task.output)를 확인
    with dsl.Condition(train_task.output > deploy_threshold):
        # 정확도가 deploy_threshold 보다 높을 때만 아래 deploy_model 컴포넌트 실행
        deploy_model(accuracy=train_task.output)


if __name__ == "__main__":
    # 파이프라인을 컴파일하여 YAML 파일로 저장합니다.
    # 이 YAML 파일을 Kubeflow UI에 업로드하여 파이프라인을 실행할 수 있습니다.
    kfp.compiler.Compiler().compile(
        pipeline_func=conditional_pipeline, package_path="conditional_pipeline.yaml"
    )
    print("Conditional pipeline compiled to conditional_pipeline.yaml")
