#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
批量任务 (Batch Operations) 使用示例

该示例演示了如何使用 KS3 批量任务接口，
包括创建、查询、删除和列出批量任务。
"""

import os
from ks3.connection import Connection
from ks3.xmlParsers.batchJob import (
    CreateJobRequest, DescribeJobResult, ListJobsResult,
    KS3PutObjectDataRedundancyTransition, KS3PutObjectAcl, KS3AccessControlList, KS3Grant,
    JobManifest, JobManifestFilter,
    JobManifestLocation, JobManifestSpec, JobOperation, JobReport,
    KS3RestoreObject, KS3DeleteObject
)

# 从环境变量获取配置
access_key = os.environ.get('KS3_IAM_ACCESS_KEY_ID')
secret_key = os.environ.get('KS3_IAM_ACCESS_KEY_SECRET')
bucket_name = os.environ.get('KS3_BUCKET')

# 初始化连接
conn = Connection(access_key, secret_key, host='ks3-cn-beijing.ksyuncs.com')
bucket = conn.get_bucket(bucket_name)


def example_create_redundancy_transition_job():
    """示例1: 创建转换为同城冗余的批量任务"""
    print("\n示例1: 创建转换为同城冗余的批量任务")
    print("-" * 50)

    # 创建清单位置
    filter1 = JobManifestFilter('krn:ksc:ks3:::bucket1', ['Prefix1', 'Prefix2'])
    filter2 = JobManifestFilter('krn:ksc:ks3:::bucket2', ['Prefix1', 'Prefix2'])
    location = JobManifestLocation([filter1, filter2])

    # 创建清单规格
    spec = JobManifestSpec('KS3BatchOperations_Bucket_V1')

    # 创建清单
    manifest = JobManifest(location, spec)

    # 创建操作 - 转换为同城冗余
    operation = JobOperation(data_redundancy_transition=KS3PutObjectDataRedundancyTransition('ZRS'))

    # 创建报告配置
    report = JobReport(
        enabled=True,
        bucket='krn:ksc:ks3:::bucket',
        prefix='job-result',
        report_scope='FailedTasksOnly'
    )

    try:
        result = conn.create_job(
            manifest=manifest,
            operation=operation,
            priority='1',
            description='转换为同城冗余任务',
            report=report,
            client_request_token='unique-token-123'
        )
        print(f"✓ 成功创建批量任务")
        print(f"  任务ID: {result.job_id}")
        print(f"  状态码: {result.status}")
        return result.job_id
    except Exception as e:
        print(f"✗ 创建任务失败: {e}")
        return None


def example_create_restore_job():
    """示例2: 创建批量解冻任务"""
    print("\n示例2: 创建批量解冻任务")
    print("-" * 50)

    # 创建清单
    filter_obj = JobManifestFilter('krn:ksc:ks3:::bucket1', ['archived/'])
    location = JobManifestLocation([filter_obj])
    spec = JobManifestSpec('KS3BatchOperations_Bucket_V1')
    manifest = JobManifest(location, spec)

    # 创建操作 - 批量解冻
    operation = JobOperation(restore_object=KS3RestoreObject(days=3, tier='Standard'))

    # 创建报告配置
    report = JobReport(
        enabled=True,
        bucket='krn:ksc:ks3:::bucket',
        prefix='restore-job-result',
        report_scope='AllTasks'
    )

    try:
        result = conn.create_job(
            manifest=manifest,
            operation=operation,
            priority='1',
            description='批量解冻归档对象',
            report=report
        )
        print(f"✓ 成功创建批量解冻任务")
        print(f"  任务ID: {result.job_id}")
        return result.job_id
    except Exception as e:
        print(f"✗ 创建任务失败: {e}")
        return None


def example_create_acl_job():
    """示例3: 创建批量修改ACL任务（使用预设ACL）"""
    print("\n示例3: 创建批量修改ACL任务（使用预设ACL）")
    print("-" * 50)

    # 创建清单
    filter_obj = JobManifestFilter('krn:ksc:ks3:::bucket1', ['public/'])
    location = JobManifestLocation([filter_obj])
    spec = JobManifestSpec('KS3BatchOperations_Bucket_V1')
    manifest = JobManifest(location, spec)

    # 创建操作 - 批量修改ACL（使用预设ACL）
    operation = JobOperation(put_object_acl=KS3PutObjectAcl('public-read'))

    # 创建报告配置
    report = JobReport(
        enabled=True,
        bucket='krn:ksc:ks3:::bucket',
        prefix='acl-job-report',
        report_scope='FailedTasksOnly'
    )

    try:
        result = conn.create_job(
            manifest=manifest,
            operation=operation,
            priority='0',
            description='批量修改ACL为public-read',
            report=report
        )
        print(f"✓ 成功创建批量修改ACL任务（预设ACL）")
        print(f"  任务ID: {result.job_id}")
        return result.job_id
    except Exception as e:
        print(f"✗ 创建任务失败: {e}")
        return None


def example_create_acl_job_with_grants():
    """示例3-2: 创建批量修改ACL任务（使用自定义ACL）"""
    print("\n示例3-2: 创建批量修改ACL任务（使用自定义ACL）")
    print("-" * 50)

    # 创建清单
    filter_obj = JobManifestFilter('krn:ksc:ks3:::bucket1', ['custom-acl/'])
    location = JobManifestLocation([filter_obj])
    spec = JobManifestSpec('KS3BatchOperations_Bucket_V1')
    manifest = JobManifest(location, spec)

    # 创建授权列表 - 可以配置多个授权
    # KS3Grant 参数: (grantee_id, permission)
    # permission 可选值: FULL_CONTROL, READ
    grants = [
        KS3Grant('123', 'FULL_CONTROL'),  # 用户ID，完全控制权限
        KS3Grant('123', 'READ'),          # 用户ID，只读权限
    ]

    # 创建自定义访问控制列表
    access_control_list = KS3AccessControlList(grants)

    # 创建操作 - 批量修改ACL（使用自定义ACL）
    operation = JobOperation(put_object_acl=KS3PutObjectAcl(access_control_list=access_control_list))

    # 创建报告配置
    report = JobReport(
        enabled=True,
        bucket='krn:ksc:ks3:::bucket',
        prefix='custom-acl-job-report',
        report_scope='FailedTasksOnly'
    )

    try:
        result = conn.create_job(
            manifest=manifest,
            operation=operation,
            priority='5',
            description='批量设置自定义ACL',
            report=report
        )
        print(f"✓ 成功创建批量修改ACL任务（自定义ACL）")
        print(f"  任务ID: {result.job_id}")
        print(f"  授权列表:")
        for grant in grants:
            print(f"    - 授权用户ID: {grant.grantee_id}, 权限: {grant.permission}")
        return result.job_id
    except Exception as e:
        print(f"✗ 创建任务失败: {e}")
        return None


def example_create_delete_job():
    """示例4: 创建批量删除任务"""
    print("\n示例4: 创建批量删除任务")
    print("-" * 50)

    # 创建清单
    filter_obj = JobManifestFilter('krn:ksc:ks3:::bucket1', ['temp/'])
    location = JobManifestLocation([filter_obj])
    spec = JobManifestSpec('KS3BatchOperations_Bucket_V1')
    manifest = JobManifest(location, spec)

    # 创建操作 - 批量删除
    operation = JobOperation(delete_object=KS3DeleteObject())

    # 创建报告配置
    report = JobReport(
        enabled=True,
        bucket='krn:ksc:ks3:::bucket',
        prefix='delete-job-report',
        report_scope='FailedTasksOnly'
    )

    try:
        result = conn.create_job(
            manifest=manifest,
            operation=operation,
            priority='0',
            description='批量删除临时对象',
            report=report
        )
        print(f"✓ 成功创建批量删除任务")
        print(f"  任务ID: {result.job_id}")
        return result.job_id
    except Exception as e:
        print(f"✗ 创建任务失败: {e}")
        return None


def example_describe_job(job_id):
    """示例5: 查询任务详情"""
    print("\n示例5: 查询任务详情")
    print("-" * 50)

    try:
        result = conn.describe_job(job_id)
        print(f"✓ 成功获取任务详情")
        print(f"  任务ID: {result.job_id}")
        print(f"  状态: {result.status}")
        print(f"  创建时间: {result.creation_time}")
        print(f"  描述: {result.description}")
        print(f"  优先级: {result.priority}")
        if result.termination_date:
            print(f"  终止时间: {result.termination_date}")
        if result.progress_summary:
            print(f"  进度: 总任务数={result.progress_summary.total_number_of_tasks}")
            print(f"  成功数量={result.progress_summary.number_of_tasks_succeeded}")
            print(f"  失败数量={result.progress_summary.number_of_tasks_failed}")
    except Exception as e:
        print(f"✗ 查询任务失败: {e}")


def example_delete_job(job_id):
    """示例6: 删除任务"""
    print("\n示例6: 删除任务")
    print("-" * 50)

    try:
        result = conn.delete_job(job_id)
        print(f"✓ 成功删除任务")
        print(f"  任务ID: {job_id}")
        print(f"  状态码: {result.status}")
    except Exception as e:
        print(f"✗ 删除任务失败: {e}")


def example_list_jobs():
    """示例7: 列出任务"""
    print("\n示例7: 列出任务")
    print("-" * 50)

    try:
        result = conn.list_jobs()
        print(f"✓ 成功获取任务列表")
        print(f"  任务数量: {len(result.jobs)}")
        for i, job in enumerate(result.jobs, 1):
            print(f"  任务{i}:")
            print(f"    ID: {job.job_id}")
            print(f"    状态: {job.status}")
            print(f"    描述: {job.description}")
            print(f"    创建时间: {job.creation_time}")
        if result.next_token:
            print(f"  下一页令牌: {result.next_token}")
    except Exception as e:
        print(f"✗ 列出任务失败: {e}")


def example_list_jobs_with_filter():
    """示例8: 列出任务（带过滤）"""
    print("\n示例8: 列出任务（带过滤）")
    print("-" * 50)

    try:
        result = conn.list_jobs(
            next_token=None,
            max_results='10',
            job_statuses='Active'
        )
        print(f"✓ 成功获取任务列表（Active状态）")
        print(f"  任务数量: {len(result.jobs)}")
        for job in result.jobs:
            print(f"  - {job.job_id}: {job.description} ({job.status})")
    except Exception as e:
        print(f"✗ 列出任务失败: {e}")


def example_update_job_priority(job_id):
    """示例9: 更新任务优先级"""
    print("\n示例9: 更新任务优先级")
    print("-" * 50)

    try:
        result = conn.update_job_priority(job_id, '0')
        print(f"✓ 成功更新任务优先级")
        print(f"  任务ID: {result.job_id}")
        print(f"  新优先级: 0")
        print("\n优先级说明:")
        print("  0 - 最高优先级")
        print("  1 - 高优先级")
        print("  10 - 中优先级")
        print("  20 - 低优先级")
    except Exception as e:
        print(f"✗ 更新任务优先级失败: {e}")


def example_xml_format():
    """示例10: 生成的 XML 请求体格式说明"""
    print("\n示例10: 生成的 XML 请求体格式")
    print("-" * 50)

    print("\n创建任务的请求 XML 格式:")
    print("""
<CreateJobRequest>
    <Manifest>
        <Location>
            <Filter>
                <Bucket>krn:ksc:ks3:::bucket1</Bucket>
                <Prefix>Prefix1</Prefix>
                <Prefix>Prefix2</Prefix>
            </Filter>
            <Filter>
                <Bucket>krn:ksc:ks3:::bucket2</Bucket>
                <Prefix>Prefix1</Prefix>
                <Prefix>Prefix2</Prefix>
            </Filter>
        </Location>
        <Spec>
            <Format>KS3BatchOperations_Bucket_V1</Format>
        </Spec>
    </Manifest>
    <Operation>
        <KS3PutObjectDataRedundancyTransition>
            <DataRedundancyType>ZRS</DataRedundancyType>
        </KS3PutObjectDataRedundancyTransition>
    </Operation>
    <Priority>1</Priority>
    <Description>任务描述</Description>
    <Report>
        <Enabled>true</Enabled>
        <Bucket>krn:ksc:ks3:::bucket</Bucket>
        <Prefix>job-result</Prefix>
        <ReportScope>FailedTasksOnly</ReportScope>
    </Report>
    <ClientRequestToken>unique-token</ClientRequestToken>
</CreateJobRequest>
    """)


if __name__ == '__main__':
    print("=" * 50)
    print("批量任务 (Batch Operations) 使用示例")
    print("=" * 50)

    # 注意: 以下示例需要有效的 KRN (Ksyun Resource Name) 和实际的 bucket 才能正常工作
    # 运行前请确保环境变量已正确配置

    # 取消下面的注释来运行示例
    # job_id = example_create_redundancy_transition_job()
    # if job_id:
    #     example_describe_job(job_id)
    #     example_update_job_priority(job_id)
    #     example_delete_job(job_id)

    # job_id2 = example_create_restore_job()
    # if job_id2:
    #     example_describe_job(job_id2)

    # example_create_acl_job()
    # example_create_delete_job()

    # example_list_jobs()
    # example_list_jobs_with_filter()

    # 显示 XML 格式说明（无需实际环境）
    example_xml_format()

    print("\n" + "=" * 50)
    print("示例运行完毕")
    print("=" * 50)