"""
update_source_identifier.py - AWS DataZone에 생성된 자산의 소스 식별자를 업데이트

이 스크립트는 다음 기능을 수행합니다:
1. DataZone에서 자산 정보 조회
2. 대시보드 이름과 ID를 결합하여 소스 식별자 생성
3. AssetCommonDetailsForm에 소스 식별자 정보 업데이트

소스 식별자는 데이터 카탈로그 내에서 자산을 고유하게 식별하기 위한 식별자입니다.

사용법:
    python update_source_identifier.py --asset-id <asset_id>
    
    필수 인자:
    --asset-id : DataZone 자산 ID
"""

import boto3
import json
import argparse
import sys

# 설정 상수 정의
AWS_REGION = '{AWS Region 입력}'
DATAZONE_DOMAIN_ID = '{DataZone 도메인 ID 입력}' 
DATAZONE_PROJECT_ID = '{DataZone 프로젝트 ID 입력}' 
TABLEAU_NAMESPACE = 'tableau'                       # Tableau 자산의 네임스페이스 기본값 

# AWS 클라이언트 초기화
datazone_client = boto3.client('datazone', region_name=AWS_REGION)

def parse_arguments():
    """
    명령줄 인자를 파싱합니다.
    """
    parser = argparse.ArgumentParser(
        description='AWS DataZone에 생성된 자산의 소스 식별자를 업데이트합니다.'
    )

    parser.add_argument(
        '--asset-id',
        type=str,
        help='업데이트할 DataZone 자산 ID (필수)'
    )

    # 인자가 없으면 도움말 출력
    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(1)

    return parser.parse_args()

def get_asset_info(asset_id):
    """
    DataZone에서 자산 정보를 조회합니다.
    
    Args:
        asset_id (str): 조회할 자산 ID
        
    Returns:
        dict: 자산 정보 딕셔너리
    """
    try:
        asset_info = datazone_client.get_asset(
            domainIdentifier=DATAZONE_DOMAIN_ID,
            identifier=asset_id
        )
        return asset_info
    except Exception as e:
        print(f"자산 정보 조회 중 오류 발생: {str(e)}")
        raise

def update_asset_source_identifier(asset_id, namespace=TABLEAU_NAMESPACE):
    """
    자산의 소스 식별자를 업데이트합니다.
    
    Args:
        asset_id (str): 업데이트할 자산 ID
        namespace (str): 소스 식별자의 네임스페이스
        
    Returns:
        str: 업데이트된 소스 식별자
    """
    # 자산 정보 로드
    print(f"자산 ID {asset_id}의 정보 조회 중...")
    asset_info = get_asset_info(asset_id)

    # 자산 정보 확인
    if not asset_info:
        print(f"자산 ID {asset_id}에 대한 정보를 찾을 수 없습니다.")
        return None

    # BI 타입을 namespace로, 대시보드 이름과 ID를 name으로 구성
    name = f"{asset_info['name']}_{asset_info['id']}"
    source_identifier = f"{namespace}/{name}"
    print(f"생성된 소스 식별자: {source_identifier}")

    # AssetCommonDetailsForm을 사용하여 소스 식별자 업데
    forms_input = []

    for form_output in asset_info['formsOutput']:
        # 원본 데이터를 변경하지 않기 위해 복사
        form_copy = form_output.copy()

        # typeRevision 필드 제거 (불필요)
        if 'typeRevision' in form_copy:
            del form_copy['typeRevision']

        # AssetCommonDetailsForm 양식 처리
        if form_copy['formName'] == 'AssetCommonDetailsForm':
            # typeName 필드 제거 (불필요)
            if 'typeName' in form_copy:
                del form_copy['typeName']

            # 소스 식별자 정보 추가
            content_dict = json.loads(form_copy['content'])
            content_dict["sourceIdentifier"] = source_identifier
            form_copy['content'] = json.dumps(content_dict, ensure_ascii=False)
        else:
            # 다른 양식의 경우 typeName을 typeIdentifier로 변경
            if 'typeName' in form_copy:
                form_copy['typeIdentifier'] = form_copy.pop('typeName')

        # 수정된 양식 추가
        forms_input.append(form_copy)

    print(f"자산 ID {asset_id}의 소스 식별자 업데이트 중...")

    response = datazone_client.create_asset_revision(
        identifier=asset_id,
        domainIdentifier=DATAZONE_DOMAIN_ID,
        formsInput=forms_input,
        glossaryTerms=asset_info.get('glossaryTerms', []),
        name=asset_info['name'],
        description=asset_info.get('description', '')
    )

    print(f"자산 ID {asset_id}의 소스 식별자가 '{source_identifier}'로 업데이트되었습니다.")

    publish_response = datazone_client.create_listing_change_set(
        action='PUBLISH',
        domainIdentifier=DATAZONE_DOMAIN_ID,
        entityIdentifier=asset_id,
        entityType='ASSET'
    )
    
    print(f"자산 ID {asset_id}이 카탈로그에 게시되었습니다.")    
    
    return source_identifier

def main():
    """
    메인 실행 함수 - 명령줄 인자를 파싱하고 자산의 소스 식별자를 업데이트합니다.
    """
    try:
        # 명령줄 인자 파싱
        args = parse_arguments()

        # 필수 인자 확인
        if not args.asset_id:
            print("오류: --asset-id 인자가 필요합니다.")
            sys.exit(1)

        asset_id = args.asset_id

        print(f"자산 소스 식별자 업데이트 시작 (자산 ID: {asset_id})...")

        # 소스 식별자 업데이트 실행
        source_identifier = update_asset_source_identifier(asset_id)

        if source_identifier:
            print(f"소스 식별자 업데이트 완료: {source_identifier}")

            # 추후 확장을 위해 소스 식별자 반환
            return source_identifier
        else:
            print("소스 식별자 업데이트 실패")
            return None

    except Exception as e:
        print(f"자산 소스 식별자 업데이트 중 오류 발생: {str(e)}")
        import traceback
        traceback.print_exc()
        return None

if __name__ == "__main__":
    main()