# Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).
from __future__ import annotations

from dataclasses import dataclass

from pants.core.util_rules.external_tool import (
    DownloadedExternalTool,
    ExternalToolRequest,
    ExternalToolVersion,
    TemplatedExternalTool,
)
from pants.engine.fs import EMPTY_DIGEST, Digest, MergeDigests
from pants.engine.internals.selectors import Get
from pants.engine.platform import Platform
from pants.engine.process import Process
from pants.engine.rules import collect_rules, rule
from pants.option.option_types import BoolOption
from pants.util.logging import LogLevel
from pants.util.meta import classproperty


class TerraformTool(TemplatedExternalTool):
    options_scope = "download-terraform"
    name = "terraform"
    help = "Terraform (https://terraform.io)"

    default_version = "1.0.7"
    default_url_template = (
        "https://releases.hashicorp.com/terraform/{version}/terraform_{version}_{platform}.zip"
    )
    default_url_platform_mapping = {
        "macos_arm64": "darwin_arm64",
        "macos_x86_64": "darwin_amd64",
        "linux_x86_64": "linux_amd64",
    }

    @classproperty
    def default_known_versions(cls):
        return [
            v.encode()
            for v in [
                ExternalToolVersion(
                    "1.0.7",
                    "macos_arm64",
                    "cbab9aca5bc4e604565697355eed185bb699733811374761b92000cc188a7725",
                    32071346,
                ),
                ExternalToolVersion(
                    "1.0.7",
                    "macos_x86_64",
                    "80ae021d6143c7f7cbf4571f65595d154561a2a25fd934b7a8ccc1ebf3014b9b",
                    33020029,
                ),
                ExternalToolVersion(
                    "1.0.7",
                    "linux_x86_64",
                    "bc79e47649e2529049a356f9e60e06b47462bf6743534a10a4c16594f443be7b",
                    32671441,
                ),
            ]
        ]

    tailor = BoolOption(
        "--tailor",
        default=True,
        help="If true, add `terraform_module` targets with the `tailor` goal.",
        advanced=True,
    )


@dataclass(frozen=True)
class TerraformProcess:
    """A request to invoke Terraform."""

    args: tuple[str, ...]
    description: str
    input_digest: Digest = EMPTY_DIGEST
    output_files: tuple[str, ...] = ()


@rule
async def setup_terraform_process(request: TerraformProcess, terraform: TerraformTool) -> Process:
    downloaded_terraform = await Get(
        DownloadedExternalTool,
        ExternalToolRequest,
        terraform.get_request(Platform.current),
    )

    input_digest = await Get(
        Digest,
        MergeDigests((request.input_digest, downloaded_terraform.digest)),
    )

    return Process(
        argv=("./terraform",) + request.args,
        input_digest=input_digest,
        output_files=request.output_files,
        description=request.description,
        level=LogLevel.DEBUG,
    )


def rules():
    return collect_rules()

@@ -404,22 +404,8 @@
 gest
-, MergeDigests
 %0Afro
@@ -2712,24 +2712,34 @@
 %0A    )%0A%0A    
+immutable_
 input_digest
@@ -2742,81 +2742,27 @@
 gest
+s
  = 
-await Get(%0A        Digest,%0A        MergeDigests((request.input_digest,
+%7B%22__terraform%22:
  dow
@@ -2789,17 +2789,9 @@
 gest
-)),%0A    )
+%7D
 %0A%0A  
@@ -2823,17 +2823,27 @@
  argv=(%22
-.
+__terraform
 /terrafo
@@ -2885,16 +2885,24 @@
 _digest=
+request.
 input_di
@@ -2903,24 +2903,81 @@
 put_digest,%0A
+        immutable_input_digests=immutable_input_digests,%0A
         outp

use immutable input for Terraform tool (#15037)