// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package auditor

import (
	"database/sql"
	"fmt"
	"strings"
	"time"

	"v.io/v23/context"
	"v.io/v23/security"
	"v.io/v23/vom"
	"v.io/x/ref/lib/security/audit"
)

// BlessingLogReader provides the Read method to read audit logs.
// Read returns a channel of BlessingEntrys whose extension matches the provided email.
type BlessingLogReader interface {
	Read(ctx *context.T, email string) <-chan BlessingEntry
}

// BlessingEntry contains important logged information about a blessed principal.
type BlessingEntry struct {
	Email              string
	Caveats            []security.Caveat
	Timestamp          time.Time // Time when the blesings were created.
	RevocationCaveatID string
	Blessings          security.Blessings
	DecodeError        error
}

// NewSQLBlessingAuditor returns an auditor for wrapping a principal with, and a BlessingLogReader
// for reading the audits made by that auditor. The config is used to construct the connection
// to the SQL database that the auditor and BlessingLogReader use.
func NewSQLBlessingAuditor(ctx *context.T, sqlDB *sql.DB) (audit.Auditor, BlessingLogReader, error) {
	db, err := newSQLDatabase(ctx, sqlDB, "BlessingAudit")
	if err != nil {
		return nil, nil, fmt.Errorf("failed to create sql db: %v", err)
	}
	auditor, reader := &blessingAuditor{db}, &blessingLogReader{db}
	return auditor, reader, nil
}

type blessingAuditor struct {
	db database
}

func (a *blessingAuditor) Audit(ctx *context.T, entry audit.Entry) error {
	if entry.Method != "Bless" {
		return nil
	}
	dbentry, err := newDatabaseEntry(entry)
	if err != nil {
		return err
	}
	return a.db.Insert(ctx, dbentry)
}

type blessingLogReader struct {
	db database
}

func (r *blessingLogReader) Read(ctx *context.T, email string) <-chan BlessingEntry {
	c := make(chan BlessingEntry)
	go r.sendAuditEvents(ctx, c, email)
	return c
}

func (r *blessingLogReader) sendAuditEvents(ctx *context.T, dst chan<- BlessingEntry, email string) {
	defer close(dst)
	dbch := r.db.Query(ctx, email)
	for dbentry := range dbch {
		dst <- newBlessingEntry(dbentry)
	}
}

func newDatabaseEntry(entry audit.Entry) (databaseEntry, error) {
	d := databaseEntry{timestamp: entry.Timestamp}
	extension, ok := entry.Arguments[2].(string)
	if !ok {
		return d, fmt.Errorf("failed to extract extension")
	}
	// Find the first email component
	for _, n := range strings.Split(extension, security.ChainSeparator) {
		// HACK ALERT: An email is the first entry to end up with
		// a single "@" in it
		if strings.Count(n, "@") == 1 {
			d.email = n
			break
		}
	}
	if len(d.email) == 0 {
		return d, fmt.Errorf("failed to extract email address from extension %q", extension)
	}
	var caveats []security.Caveat
	for _, arg := range entry.Arguments[3:] {
		if cav, ok := arg.(security.Caveat); !ok {
			return d, fmt.Errorf("failed to extract Caveat")
		} else {
			caveats = append(caveats, cav)
		}
	}
	var blessings security.Blessings
	if blessings, ok = entry.Results[0].(security.Blessings); !ok {
		return d, fmt.Errorf("failed to extract result blessing")
	}
	var err error
	if d.blessings, err = vom.Encode(blessings); err != nil {
		return d, err
	}
	if d.caveats, err = vom.Encode(caveats); err != nil {
		return d, err
	}
	return d, nil
}

func newBlessingEntry(dbentry databaseEntry) BlessingEntry {
	if dbentry.decodeErr != nil {
		return BlessingEntry{DecodeError: dbentry.decodeErr}
	}
	b := BlessingEntry{
		Email:     dbentry.email,
		Timestamp: dbentry.timestamp,
	}
	if err := vom.Decode(dbentry.blessings, &b.Blessings); err != nil {
		return BlessingEntry{DecodeError: fmt.Errorf("failed to decode blessings: %s", err)}
	}
	if err := vom.Decode(dbentry.caveats, &b.Caveats); err != nil {
		return BlessingEntry{DecodeError: fmt.Errorf("failed to decode caveats: %s", err)}
	}
	b.RevocationCaveatID = revocationCaveatID(b.Caveats)
	return b
}

func revocationCaveatID(caveats []security.Caveat) string {
	for _, cav := range caveats {
		if tp := cav.ThirdPartyDetails(); tp != nil {
			return tp.ID()
		}
	}
	return ""
}
