// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

// ----------------------------------------------------------------------------
//
//     ***     AUTO GENERATED CODE    ***    Type: DCL     ***
//
// ----------------------------------------------------------------------------
//
//     This file is managed by Magic Modules (https://github.com/GoogleCloudPlatform/magic-modules)
//     and is based on the DCL (https://github.com/GoogleCloudPlatform/declarative-resource-client-library).
//     Changes will need to be made to the DCL or Magic Modules instead of here.
//
//     We are not currently able to accept contributions to this file. If changes
//     are required, please file an issue at https://github.com/hashicorp/terraform-provider-google/issues/new/choose
//
// ----------------------------------------------------------------------------

package firebaserules

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

	dcl "github.com/GoogleCloudPlatform/declarative-resource-client-library/dcl"
	firebaserules "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/firebaserules/beta"

	"github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgdclresource"
	"github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource"
	transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport"
)

func ResourceFirebaserulesRuleset() *schema.Resource {
	return &schema.Resource{
		Create: resourceFirebaserulesRulesetCreate,
		Read:   resourceFirebaserulesRulesetRead,
		Delete: resourceFirebaserulesRulesetDelete,

		Importer: &schema.ResourceImporter{
			State: resourceFirebaserulesRulesetImport,
		},

		Timeouts: &schema.ResourceTimeout{
			Create: schema.DefaultTimeout(20 * time.Minute),
			Delete: schema.DefaultTimeout(20 * time.Minute),
		},
		CustomizeDiff: customdiff.All(
			tpgresource.DefaultProviderProject,
		),

		Schema: map[string]*schema.Schema{
			"source": {
				Type:        schema.TypeList,
				Required:    true,
				ForceNew:    true,
				Description: "`Source` for the `Ruleset`.",
				MaxItems:    1,
				Elem:        FirebaserulesRulesetSourceSchema(),
			},

			"project": {
				Type:             schema.TypeString,
				Computed:         true,
				Optional:         true,
				ForceNew:         true,
				DiffSuppressFunc: tpgresource.CompareSelfLinkOrResourceName,
				Description:      "The project for the resource",
			},

			"create_time": {
				Type:        schema.TypeString,
				Computed:    true,
				Description: "Output only. Time the `Ruleset` was created.",
			},

			"metadata": {
				Type:        schema.TypeList,
				Computed:    true,
				Description: "Output only. The metadata for this ruleset.",
				Elem:        FirebaserulesRulesetMetadataSchema(),
			},

			"name": {
				Type:        schema.TypeString,
				Computed:    true,
				Description: "Output only. Name of the `Ruleset`. The ruleset_id is auto generated by the service. Format: `projects/{project_id}/rulesets/{ruleset_id}`",
			},
		},
	}
}

func FirebaserulesRulesetSourceSchema() *schema.Resource {
	return &schema.Resource{
		Schema: map[string]*schema.Schema{
			"files": {
				Type:        schema.TypeList,
				Required:    true,
				ForceNew:    true,
				Description: "`File` set constituting the `Source` bundle.",
				Elem:        FirebaserulesRulesetSourceFilesSchema(),
			},

			"language": {
				Type:        schema.TypeString,
				Optional:    true,
				ForceNew:    true,
				Description: "`Language` of the `Source` bundle. If unspecified, the language will default to `FIREBASE_RULES`. Possible values: LANGUAGE_UNSPECIFIED, FIREBASE_RULES, EVENT_FLOW_TRIGGERS",
			},
		},
	}
}

func FirebaserulesRulesetSourceFilesSchema() *schema.Resource {
	return &schema.Resource{
		Schema: map[string]*schema.Schema{
			"content": {
				Type:        schema.TypeString,
				Required:    true,
				ForceNew:    true,
				Description: "Textual Content.",
			},

			"name": {
				Type:        schema.TypeString,
				Required:    true,
				ForceNew:    true,
				Description: "File name.",
			},

			"fingerprint": {
				Type:        schema.TypeString,
				Optional:    true,
				ForceNew:    true,
				Description: "Fingerprint (e.g. github sha) associated with the `File`.",
			},
		},
	}
}

func FirebaserulesRulesetMetadataSchema() *schema.Resource {
	return &schema.Resource{
		Schema: map[string]*schema.Schema{
			"services": {
				Type:        schema.TypeList,
				Computed:    true,
				Description: "Services that this ruleset has declarations for (e.g., \"cloud.firestore\"). There may be 0+ of these.",
				Elem:        &schema.Schema{Type: schema.TypeString},
			},
		},
	}
}

func resourceFirebaserulesRulesetCreate(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*transport_tpg.Config)
	project, err := tpgresource.GetProject(d, config)
	if err != nil {
		return err
	}

	obj := &firebaserules.Ruleset{
		Source:  expandFirebaserulesRulesetSource(d.Get("source")),
		Project: dcl.String(project),
	}

	id, err := obj.ID()
	if err != nil {
		return fmt.Errorf("error constructing id: %s", err)
	}
	d.SetId(id)
	directive := tpgdclresource.CreateDirective
	userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
	if err != nil {
		return err
	}
	billingProject := project
	// err == nil indicates that the billing_project value was found
	if bp, err := tpgresource.GetBillingProject(d, config); err == nil {
		billingProject = bp
	}
	client := transport_tpg.NewDCLFirebaserulesClient(config, userAgent, billingProject, d.Timeout(schema.TimeoutCreate))
	if bp, err := tpgresource.ReplaceVars(d, config, client.Config.BasePath); err != nil {
		d.SetId("")
		return fmt.Errorf("Could not format %q: %w", client.Config.BasePath, err)
	} else {
		client.Config.BasePath = bp
	}
	res, err := client.ApplyRuleset(context.Background(), obj, directive...)

	if _, ok := err.(dcl.DiffAfterApplyError); ok {
		log.Printf("[DEBUG] Diff after apply returned from the DCL: %s", err)
	} else if err != nil {
		// The resource didn't actually create
		d.SetId("")
		return fmt.Errorf("Error creating Ruleset: %s", err)
	}

	if err = d.Set("name", res.Name); err != nil {
		return fmt.Errorf("error setting name in state: %s", err)
	}
	// ID has a server-generated value, set again after creation.

	id, err = res.ID()
	if err != nil {
		return fmt.Errorf("error constructing id: %s", err)
	}
	d.SetId(id)

	log.Printf("[DEBUG] Finished creating Ruleset %q: %#v", d.Id(), res)

	return resourceFirebaserulesRulesetRead(d, meta)
}

func resourceFirebaserulesRulesetRead(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*transport_tpg.Config)
	project, err := tpgresource.GetProject(d, config)
	if err != nil {
		return err
	}

	obj := &firebaserules.Ruleset{
		Source:  expandFirebaserulesRulesetSource(d.Get("source")),
		Project: dcl.String(project),
		Name:    dcl.StringOrNil(d.Get("name").(string)),
	}

	userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
	if err != nil {
		return err
	}
	billingProject := project
	// err == nil indicates that the billing_project value was found
	if bp, err := tpgresource.GetBillingProject(d, config); err == nil {
		billingProject = bp
	}
	client := transport_tpg.NewDCLFirebaserulesClient(config, userAgent, billingProject, d.Timeout(schema.TimeoutRead))
	if bp, err := tpgresource.ReplaceVars(d, config, client.Config.BasePath); err != nil {
		d.SetId("")
		return fmt.Errorf("Could not format %q: %w", client.Config.BasePath, err)
	} else {
		client.Config.BasePath = bp
	}
	res, err := client.GetRuleset(context.Background(), obj)
	if err != nil {
		resourceName := fmt.Sprintf("FirebaserulesRuleset %q", d.Id())
		return tpgdclresource.HandleNotFoundDCLError(err, d, resourceName)
	}

	if err = d.Set("source", flattenFirebaserulesRulesetSource(res.Source)); err != nil {
		return fmt.Errorf("error setting source in state: %s", err)
	}
	if err = d.Set("project", res.Project); err != nil {
		return fmt.Errorf("error setting project in state: %s", err)
	}
	if err = d.Set("create_time", res.CreateTime); err != nil {
		return fmt.Errorf("error setting create_time in state: %s", err)
	}
	if err = d.Set("metadata", flattenFirebaserulesRulesetMetadata(res.Metadata)); err != nil {
		return fmt.Errorf("error setting metadata in state: %s", err)
	}
	if err = d.Set("name", res.Name); err != nil {
		return fmt.Errorf("error setting name in state: %s", err)
	}

	return nil
}

func resourceFirebaserulesRulesetDelete(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*transport_tpg.Config)
	project, err := tpgresource.GetProject(d, config)
	if err != nil {
		return err
	}

	obj := &firebaserules.Ruleset{
		Source:  expandFirebaserulesRulesetSource(d.Get("source")),
		Project: dcl.String(project),
		Name:    dcl.StringOrNil(d.Get("name").(string)),
	}

	log.Printf("[DEBUG] Deleting Ruleset %q", d.Id())
	userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
	if err != nil {
		return err
	}
	billingProject := project
	// err == nil indicates that the billing_project value was found
	if bp, err := tpgresource.GetBillingProject(d, config); err == nil {
		billingProject = bp
	}
	client := transport_tpg.NewDCLFirebaserulesClient(config, userAgent, billingProject, d.Timeout(schema.TimeoutDelete))
	if bp, err := tpgresource.ReplaceVars(d, config, client.Config.BasePath); err != nil {
		d.SetId("")
		return fmt.Errorf("Could not format %q: %w", client.Config.BasePath, err)
	} else {
		client.Config.BasePath = bp
	}
	if err := client.DeleteRuleset(context.Background(), obj); err != nil {
		return fmt.Errorf("Error deleting Ruleset: %s", err)
	}

	log.Printf("[DEBUG] Finished deleting Ruleset %q", d.Id())
	return nil
}

func resourceFirebaserulesRulesetImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
	config := meta.(*transport_tpg.Config)

	if err := tpgresource.ParseImportId([]string{
		"projects/(?P<project>[^/]+)/rulesets/(?P<name>[^/]+)",
		"(?P<project>[^/]+)/(?P<name>[^/]+)",
		"(?P<name>[^/]+)",
	}, d, config); err != nil {
		return nil, err
	}

	// Replace import id for the resource id
	id, err := tpgresource.ReplaceVarsForId(d, config, "projects/{{project}}/rulesets/{{name}}")
	if err != nil {
		return nil, fmt.Errorf("Error constructing id: %s", err)
	}
	d.SetId(id)

	return []*schema.ResourceData{d}, nil
}

func expandFirebaserulesRulesetSource(o interface{}) *firebaserules.RulesetSource {
	if o == nil {
		return firebaserules.EmptyRulesetSource
	}
	objArr := o.([]interface{})
	if len(objArr) == 0 || objArr[0] == nil {
		return firebaserules.EmptyRulesetSource
	}
	obj := objArr[0].(map[string]interface{})
	return &firebaserules.RulesetSource{
		Files:    expandFirebaserulesRulesetSourceFilesArray(obj["files"]),
		Language: firebaserules.RulesetSourceLanguageEnumRef(obj["language"].(string)),
	}
}

func flattenFirebaserulesRulesetSource(obj *firebaserules.RulesetSource) interface{} {
	if obj == nil || obj.Empty() {
		return nil
	}
	transformed := map[string]interface{}{
		"files":    flattenFirebaserulesRulesetSourceFilesArray(obj.Files),
		"language": obj.Language,
	}

	return []interface{}{transformed}

}
func expandFirebaserulesRulesetSourceFilesArray(o interface{}) []firebaserules.RulesetSourceFiles {
	if o == nil {
		return make([]firebaserules.RulesetSourceFiles, 0)
	}

	objs := o.([]interface{})
	if len(objs) == 0 || objs[0] == nil {
		return make([]firebaserules.RulesetSourceFiles, 0)
	}

	items := make([]firebaserules.RulesetSourceFiles, 0, len(objs))
	for _, item := range objs {
		i := expandFirebaserulesRulesetSourceFiles(item)
		items = append(items, *i)
	}

	return items
}

func expandFirebaserulesRulesetSourceFiles(o interface{}) *firebaserules.RulesetSourceFiles {
	if o == nil {
		return firebaserules.EmptyRulesetSourceFiles
	}

	obj := o.(map[string]interface{})
	return &firebaserules.RulesetSourceFiles{
		Content:     dcl.String(obj["content"].(string)),
		Name:        dcl.String(obj["name"].(string)),
		Fingerprint: dcl.String(obj["fingerprint"].(string)),
	}
}

func flattenFirebaserulesRulesetSourceFilesArray(objs []firebaserules.RulesetSourceFiles) []interface{} {
	if objs == nil {
		return nil
	}

	items := []interface{}{}
	for _, item := range objs {
		i := flattenFirebaserulesRulesetSourceFiles(&item)
		items = append(items, i)
	}

	return items
}

func flattenFirebaserulesRulesetSourceFiles(obj *firebaserules.RulesetSourceFiles) interface{} {
	if obj == nil || obj.Empty() {
		return nil
	}
	transformed := map[string]interface{}{
		"content":     obj.Content,
		"name":        obj.Name,
		"fingerprint": obj.Fingerprint,
	}

	return transformed

}

func flattenFirebaserulesRulesetMetadata(obj *firebaserules.RulesetMetadata) interface{} {
	if obj == nil || obj.Empty() {
		return nil
	}
	transformed := map[string]interface{}{
		"services": obj.Services,
	}

	return []interface{}{transformed}

}
