/*
 * 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 avatica provides an Apache Phoenix Query Server/Avatica driver for Go's database/sql package.

Quickstart

Import the database/sql package along with the avatica driver.

	import "database/sql"
	import _ "github.com/apache/calcite-avatica-go/v3"

	db, err := sql.Open("avatica", "http://phoenix-query-server:8765")

See https://calcite.apache.org/avatica/go_client_reference.html for more details
*/
package avatica

import (
	"context"
	"database/sql"
	"database/sql/driver"
	"fmt"

	"github.com/apache/calcite-avatica-go/v3/generic"
	"github.com/apache/calcite-avatica-go/v3/hsqldb"
	"github.com/apache/calcite-avatica-go/v3/message"
	"github.com/apache/calcite-avatica-go/v3/phoenix"
	"github.com/hashicorp/go-uuid"
)

// Driver is exported to allow it to be used directly.
type Driver struct{}

// Open a Connection to the server.
// See https://github.com/apache/calcite-avatica-go#dsn for more information
// on how the DSN is formatted.
func (a *Driver) Open(dsn string) (driver.Conn, error) {

	config, err := ParseDSN(dsn)

	if err != nil {
		return nil, fmt.Errorf("Unable to open connection: %s", err)
	}

	httpClient, err := NewHTTPClient(config.endpoint, httpClientAuthConfig{
		authenticationType:  config.authentication,
		username:            config.avaticaUser,
		password:            config.avaticaPassword,
		principal:           config.principal,
		keytab:              config.keytab,
		krb5Conf:            config.krb5Conf,
		krb5CredentialCache: config.krb5CredentialCache,
	})

	if err != nil {
		return nil, fmt.Errorf("Unable to create HTTP client: %s", err)
	}

	connectionId, err := uuid.GenerateUUID()
	if err != nil {
		return nil, fmt.Errorf("Error generating connection id: %s", err)
	}

	info := map[string]string{
		"AutoCommit":  "true",
		"Consistency": "8",
	}

	if config.user != "" {
		info["user"] = config.user
	}

	if config.password != "" {
		info["password"] = config.password
	}

	conn := &conn{
		connectionId: connectionId,
		httpClient:   httpClient,
		config:       config,
	}

	// Open a connection to the server
	req := &message.OpenConnectionRequest{
		ConnectionId: connectionId,
		Info:         info,
	}

	if config.schema != "" {
		req.Info["schema"] = config.schema
	}

	_, err = httpClient.post(context.Background(), req)

	if err != nil {
		return nil, conn.avaticaErrorToResponseErrorOrError(err)
	}

	response, err := httpClient.post(context.Background(), &message.DatabasePropertyRequest{
		ConnectionId: connectionId,
	})

	if err != nil {
		return nil, conn.avaticaErrorToResponseErrorOrError(err)
	}

	databasePropertyResponse := response.(*message.DatabasePropertyResponse)

	adapter := ""

	for _, property := range databasePropertyResponse.Props {
		if property.Key.Name == "GET_DRIVER_NAME" {
			adapter = property.Value.StringValue
		}
	}

	conn.adapter = getAdapter(adapter)

	return conn, nil
}

func getAdapter(e string) Adapter {
	switch e {
	case "HSQL Database Engine Driver":
		return hsqldb.Adapter{}
	case "PhoenixEmbeddedDriver":
		return phoenix.Adapter{}
	default:
		return generic.Adapter{}
	}
}

func init() {
	sql.Register("avatica", &Driver{})
}
