// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.

package com.azure.resourcemanager.postgresqlflexibleserver.implementation;

import com.azure.core.management.Region;
import com.azure.core.management.SystemData;
import com.azure.core.util.Context;
import com.azure.resourcemanager.postgresqlflexibleserver.fluent.models.MigrationResourceInner;
import com.azure.resourcemanager.postgresqlflexibleserver.models.CancelEnum;
import com.azure.resourcemanager.postgresqlflexibleserver.models.DbServerMetadata;
import com.azure.resourcemanager.postgresqlflexibleserver.models.LogicalReplicationOnSourceDbEnum;
import com.azure.resourcemanager.postgresqlflexibleserver.models.MigrationMode;
import com.azure.resourcemanager.postgresqlflexibleserver.models.MigrationResource;
import com.azure.resourcemanager.postgresqlflexibleserver.models.MigrationResourceForPatch;
import com.azure.resourcemanager.postgresqlflexibleserver.models.MigrationSecretParameters;
import com.azure.resourcemanager.postgresqlflexibleserver.models.MigrationStatus;
import com.azure.resourcemanager.postgresqlflexibleserver.models.OverwriteDbsInTargetEnum;
import com.azure.resourcemanager.postgresqlflexibleserver.models.StartDataMigrationEnum;
import com.azure.resourcemanager.postgresqlflexibleserver.models.TriggerCutoverEnum;
import java.time.OffsetDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public final class MigrationResourceImpl
    implements MigrationResource, MigrationResource.Definition, MigrationResource.Update {
    private MigrationResourceInner innerObject;

    private final com.azure.resourcemanager.postgresqlflexibleserver.PostgreSqlManager serviceManager;

    public String id() {
        return this.innerModel().id();
    }

    public String name() {
        return this.innerModel().name();
    }

    public String type() {
        return this.innerModel().type();
    }

    public String location() {
        return this.innerModel().location();
    }

    public Map<String, String> tags() {
        Map<String, String> inner = this.innerModel().tags();
        if (inner != null) {
            return Collections.unmodifiableMap(inner);
        } else {
            return Collections.emptyMap();
        }
    }

    public SystemData systemData() {
        return this.innerModel().systemData();
    }

    public String migrationId() {
        return this.innerModel().migrationId();
    }

    public MigrationStatus currentStatus() {
        return this.innerModel().currentStatus();
    }

    public MigrationMode migrationMode() {
        return this.innerModel().migrationMode();
    }

    public DbServerMetadata sourceDbServerMetadata() {
        return this.innerModel().sourceDbServerMetadata();
    }

    public DbServerMetadata targetDbServerMetadata() {
        return this.innerModel().targetDbServerMetadata();
    }

    public String sourceDbServerResourceId() {
        return this.innerModel().sourceDbServerResourceId();
    }

    public String sourceDbServerFullyQualifiedDomainName() {
        return this.innerModel().sourceDbServerFullyQualifiedDomainName();
    }

    public String targetDbServerResourceId() {
        return this.innerModel().targetDbServerResourceId();
    }

    public String targetDbServerFullyQualifiedDomainName() {
        return this.innerModel().targetDbServerFullyQualifiedDomainName();
    }

    public MigrationSecretParameters secretParameters() {
        return this.innerModel().secretParameters();
    }

    public List<String> dbsToMigrate() {
        List<String> inner = this.innerModel().dbsToMigrate();
        if (inner != null) {
            return Collections.unmodifiableList(inner);
        } else {
            return Collections.emptyList();
        }
    }

    public LogicalReplicationOnSourceDbEnum setupLogicalReplicationOnSourceDbIfNeeded() {
        return this.innerModel().setupLogicalReplicationOnSourceDbIfNeeded();
    }

    public OverwriteDbsInTargetEnum overwriteDbsInTarget() {
        return this.innerModel().overwriteDbsInTarget();
    }

    public OffsetDateTime migrationWindowStartTimeInUtc() {
        return this.innerModel().migrationWindowStartTimeInUtc();
    }

    public OffsetDateTime migrationWindowEndTimeInUtc() {
        return this.innerModel().migrationWindowEndTimeInUtc();
    }

    public StartDataMigrationEnum startDataMigration() {
        return this.innerModel().startDataMigration();
    }

    public TriggerCutoverEnum triggerCutover() {
        return this.innerModel().triggerCutover();
    }

    public List<String> dbsToTriggerCutoverOn() {
        List<String> inner = this.innerModel().dbsToTriggerCutoverOn();
        if (inner != null) {
            return Collections.unmodifiableList(inner);
        } else {
            return Collections.emptyList();
        }
    }

    public CancelEnum cancel() {
        return this.innerModel().cancel();
    }

    public List<String> dbsToCancelMigrationOn() {
        List<String> inner = this.innerModel().dbsToCancelMigrationOn();
        if (inner != null) {
            return Collections.unmodifiableList(inner);
        } else {
            return Collections.emptyList();
        }
    }

    public Region region() {
        return Region.fromName(this.regionName());
    }

    public String regionName() {
        return this.location();
    }

    public String resourceGroupName() {
        return resourceGroupName;
    }

    public MigrationResourceInner innerModel() {
        return this.innerObject;
    }

    private com.azure.resourcemanager.postgresqlflexibleserver.PostgreSqlManager manager() {
        return this.serviceManager;
    }

    private String subscriptionId;

    private String resourceGroupName;

    private String targetDbServerName;

    private String migrationName;

    private MigrationResourceForPatch updateParameters;

    public MigrationResourceImpl withExistingFlexibleServer(
        String subscriptionId, String resourceGroupName, String targetDbServerName) {
        this.subscriptionId = subscriptionId;
        this.resourceGroupName = resourceGroupName;
        this.targetDbServerName = targetDbServerName;
        return this;
    }

    public MigrationResource create() {
        this.innerObject =
            serviceManager
                .serviceClient()
                .getMigrations()
                .createWithResponse(
                    subscriptionId,
                    resourceGroupName,
                    targetDbServerName,
                    migrationName,
                    this.innerModel(),
                    Context.NONE)
                .getValue();
        return this;
    }

    public MigrationResource create(Context context) {
        this.innerObject =
            serviceManager
                .serviceClient()
                .getMigrations()
                .createWithResponse(
                    subscriptionId, resourceGroupName, targetDbServerName, migrationName, this.innerModel(), context)
                .getValue();
        return this;
    }

    MigrationResourceImpl(
        String name, com.azure.resourcemanager.postgresqlflexibleserver.PostgreSqlManager serviceManager) {
        this.innerObject = new MigrationResourceInner();
        this.serviceManager = serviceManager;
        this.migrationName = name;
    }

    public MigrationResourceImpl update() {
        this.updateParameters = new MigrationResourceForPatch();
        return this;
    }

    public MigrationResource apply() {
        this.innerObject =
            serviceManager
                .serviceClient()
                .getMigrations()
                .updateWithResponse(
                    subscriptionId,
                    resourceGroupName,
                    targetDbServerName,
                    migrationName,
                    updateParameters,
                    Context.NONE)
                .getValue();
        return this;
    }

    public MigrationResource apply(Context context) {
        this.innerObject =
            serviceManager
                .serviceClient()
                .getMigrations()
                .updateWithResponse(
                    subscriptionId, resourceGroupName, targetDbServerName, migrationName, updateParameters, context)
                .getValue();
        return this;
    }

    MigrationResourceImpl(
        MigrationResourceInner innerObject,
        com.azure.resourcemanager.postgresqlflexibleserver.PostgreSqlManager serviceManager) {
        this.innerObject = innerObject;
        this.serviceManager = serviceManager;
        this.subscriptionId = Utils.getValueFromIdByName(innerObject.id(), "subscriptions");
        this.resourceGroupName = Utils.getValueFromIdByName(innerObject.id(), "resourceGroups");
        this.targetDbServerName = Utils.getValueFromIdByName(innerObject.id(), "flexibleServers");
        this.migrationName = Utils.getValueFromIdByName(innerObject.id(), "migrations");
    }

    public MigrationResource refresh() {
        this.innerObject =
            serviceManager
                .serviceClient()
                .getMigrations()
                .getWithResponse(subscriptionId, resourceGroupName, targetDbServerName, migrationName, Context.NONE)
                .getValue();
        return this;
    }

    public MigrationResource refresh(Context context) {
        this.innerObject =
            serviceManager
                .serviceClient()
                .getMigrations()
                .getWithResponse(subscriptionId, resourceGroupName, targetDbServerName, migrationName, context)
                .getValue();
        return this;
    }

    public MigrationResourceImpl withRegion(Region location) {
        this.innerModel().withLocation(location.toString());
        return this;
    }

    public MigrationResourceImpl withRegion(String location) {
        this.innerModel().withLocation(location);
        return this;
    }

    public MigrationResourceImpl withTags(Map<String, String> tags) {
        if (isInCreateMode()) {
            this.innerModel().withTags(tags);
            return this;
        } else {
            this.updateParameters.withTags(tags);
            return this;
        }
    }

    public MigrationResourceImpl withMigrationMode(MigrationMode migrationMode) {
        if (isInCreateMode()) {
            this.innerModel().withMigrationMode(migrationMode);
            return this;
        } else {
            this.updateParameters.withMigrationMode(migrationMode);
            return this;
        }
    }

    public MigrationResourceImpl withSourceDbServerResourceId(String sourceDbServerResourceId) {
        if (isInCreateMode()) {
            this.innerModel().withSourceDbServerResourceId(sourceDbServerResourceId);
            return this;
        } else {
            this.updateParameters.withSourceDbServerResourceId(sourceDbServerResourceId);
            return this;
        }
    }

    public MigrationResourceImpl withSourceDbServerFullyQualifiedDomainName(
        String sourceDbServerFullyQualifiedDomainName) {
        if (isInCreateMode()) {
            this.innerModel().withSourceDbServerFullyQualifiedDomainName(sourceDbServerFullyQualifiedDomainName);
            return this;
        } else {
            this.updateParameters.withSourceDbServerFullyQualifiedDomainName(sourceDbServerFullyQualifiedDomainName);
            return this;
        }
    }

    public MigrationResourceImpl withTargetDbServerFullyQualifiedDomainName(
        String targetDbServerFullyQualifiedDomainName) {
        if (isInCreateMode()) {
            this.innerModel().withTargetDbServerFullyQualifiedDomainName(targetDbServerFullyQualifiedDomainName);
            return this;
        } else {
            this.updateParameters.withTargetDbServerFullyQualifiedDomainName(targetDbServerFullyQualifiedDomainName);
            return this;
        }
    }

    public MigrationResourceImpl withSecretParameters(MigrationSecretParameters secretParameters) {
        if (isInCreateMode()) {
            this.innerModel().withSecretParameters(secretParameters);
            return this;
        } else {
            this.updateParameters.withSecretParameters(secretParameters);
            return this;
        }
    }

    public MigrationResourceImpl withDbsToMigrate(List<String> dbsToMigrate) {
        if (isInCreateMode()) {
            this.innerModel().withDbsToMigrate(dbsToMigrate);
            return this;
        } else {
            this.updateParameters.withDbsToMigrate(dbsToMigrate);
            return this;
        }
    }

    public MigrationResourceImpl withSetupLogicalReplicationOnSourceDbIfNeeded(
        LogicalReplicationOnSourceDbEnum setupLogicalReplicationOnSourceDbIfNeeded) {
        if (isInCreateMode()) {
            this.innerModel().withSetupLogicalReplicationOnSourceDbIfNeeded(setupLogicalReplicationOnSourceDbIfNeeded);
            return this;
        } else {
            this
                .updateParameters
                .withSetupLogicalReplicationOnSourceDbIfNeeded(setupLogicalReplicationOnSourceDbIfNeeded);
            return this;
        }
    }

    public MigrationResourceImpl withOverwriteDbsInTarget(OverwriteDbsInTargetEnum overwriteDbsInTarget) {
        if (isInCreateMode()) {
            this.innerModel().withOverwriteDbsInTarget(overwriteDbsInTarget);
            return this;
        } else {
            this.updateParameters.withOverwriteDbsInTarget(overwriteDbsInTarget);
            return this;
        }
    }

    public MigrationResourceImpl withMigrationWindowStartTimeInUtc(OffsetDateTime migrationWindowStartTimeInUtc) {
        if (isInCreateMode()) {
            this.innerModel().withMigrationWindowStartTimeInUtc(migrationWindowStartTimeInUtc);
            return this;
        } else {
            this.updateParameters.withMigrationWindowStartTimeInUtc(migrationWindowStartTimeInUtc);
            return this;
        }
    }

    public MigrationResourceImpl withMigrationWindowEndTimeInUtc(OffsetDateTime migrationWindowEndTimeInUtc) {
        this.innerModel().withMigrationWindowEndTimeInUtc(migrationWindowEndTimeInUtc);
        return this;
    }

    public MigrationResourceImpl withStartDataMigration(StartDataMigrationEnum startDataMigration) {
        if (isInCreateMode()) {
            this.innerModel().withStartDataMigration(startDataMigration);
            return this;
        } else {
            this.updateParameters.withStartDataMigration(startDataMigration);
            return this;
        }
    }

    public MigrationResourceImpl withTriggerCutover(TriggerCutoverEnum triggerCutover) {
        if (isInCreateMode()) {
            this.innerModel().withTriggerCutover(triggerCutover);
            return this;
        } else {
            this.updateParameters.withTriggerCutover(triggerCutover);
            return this;
        }
    }

    public MigrationResourceImpl withDbsToTriggerCutoverOn(List<String> dbsToTriggerCutoverOn) {
        if (isInCreateMode()) {
            this.innerModel().withDbsToTriggerCutoverOn(dbsToTriggerCutoverOn);
            return this;
        } else {
            this.updateParameters.withDbsToTriggerCutoverOn(dbsToTriggerCutoverOn);
            return this;
        }
    }

    public MigrationResourceImpl withCancel(CancelEnum cancel) {
        if (isInCreateMode()) {
            this.innerModel().withCancel(cancel);
            return this;
        } else {
            this.updateParameters.withCancel(cancel);
            return this;
        }
    }

    public MigrationResourceImpl withDbsToCancelMigrationOn(List<String> dbsToCancelMigrationOn) {
        if (isInCreateMode()) {
            this.innerModel().withDbsToCancelMigrationOn(dbsToCancelMigrationOn);
            return this;
        } else {
            this.updateParameters.withDbsToCancelMigrationOn(dbsToCancelMigrationOn);
            return this;
        }
    }

    private boolean isInCreateMode() {
        return this.innerModel().id() == null;
    }
}
