// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package fhirio

import (
	"testing"

	"github.com/apache/beam/sdks/v2/go/pkg/beam"
	"github.com/apache/beam/sdks/v2/go/pkg/beam/testing/passert"
	"github.com/apache/beam/sdks/v2/go/pkg/beam/testing/ptest"
	"google.golang.org/api/healthcare/v1"
)

func TestDeidentify_Error(t *testing.T) {
	p, s := beam.NewPipelineWithRoot()
	out := deidentify(s, "src", "dst", nil, requestReturnErrorFakeClient)
	passert.Empty(s, out)

	result := ptest.RunAndValidate(t, p)
	validateCounter(t, result, operationErrorCounterName, 1)
	validateCounter(t, result, operationSuccessCounterName, 0)
	validateCounter(t, result, errorCounterName, 0)
	validateCounter(t, result, successCounterName, 0)
}

func TestDeidentify_Success(t *testing.T) {
	p, s := beam.NewPipelineWithRoot()
	out := deidentify(s, "src", "dst", nil, &fakeFhirStoreClient{
		fakeDeidentify: func(string, string, *healthcare.DeidentifyConfig) (operationResults, error) {
			return operationResults{
				Successes: 5,
				Failures:  2,
			}, nil
		},
	})
	passert.Count(s, out, "", 1)

	result := ptest.RunAndValidate(t, p)
	validateCounter(t, result, operationErrorCounterName, 0)
	validateCounter(t, result, operationSuccessCounterName, 1)
	validateCounter(t, result, errorCounterName, 2)
	validateCounter(t, result, successCounterName, 5)
}
