package main

import (
	"bytes"
	"flag"
	"io"
	"net/mail"
	"xinu.tv/email/db"

	"github.com/golang/glog"
)

var (
	all = flag.Bool("all", false,
		"extract headers from all messages. Default is to only extract from unprocessed messages.")
)

func insertHeaders(c *db.Conn, hash string, r io.Reader) error {
	msg, err := mail.ReadMessage(r)
	if err != nil {
		return err
	}
	glog.Infoln("Insert headers", hash)
	return c.InsertHeaders(hash, msg.Header)
}

func insertSearchHeaders(c *db.Conn, hash string, r io.Reader) error {
	msg, err := mail.ReadMessage(r)
	if err != nil {
		return err
	}
	glog.Infoln("Insert search headers", hash)
	return c.InsertSearchHeaders(hash, msg.Header)
}

func insertAllHeaders(c *db.Conn, all bool) error {
	oCh := make(chan db.Original)
	errc := make(chan error)
	donec := make(chan struct{})
	defer close(donec)
	if all {
		go c.Originals(oCh, errc, donec)
	} else {
		go c.OriginalsNotInTable("header", oCh, errc, donec)
	}
	for {
		select {
		case o := <-oCh:
			r := bytes.NewReader(o.Blob)
			if err := insertHeaders(c, o.Hash, r); err != nil {
				glog.Errorln(o, "insertHeaders", err)
				return err
			}
		case err := <-errc:
			return err
		}
	}
}

func insertAllSearchHeaders(c *db.Conn, all bool) error {
	oCh := make(chan db.Original)
	errc := make(chan error)
	donec := make(chan struct{})
	defer close(donec)
	if all {
		go c.Originals(oCh, errc, donec)
	} else {
		go c.OriginalsNotInTable("search_header", oCh, errc, donec)
	}
	for {
		select {
		case o := <-oCh:
			r := bytes.NewReader(o.Blob)
			if err := insertSearchHeaders(c, o.Hash, r); err != nil {
				glog.Errorln(o.Hash, "insertSearchHeaders", err)
				return err
			}
		case err := <-errc:
			return err
		}
	}
}

func main() {
	defer glog.Flush()
	flag.Parse()

	c, err := db.NewConn("")
	if err != nil {
		glog.Fatal(err)
	}

	if err := insertAllHeaders(c, *all); err != nil {
		glog.Fatal(err)
	}

	if err := insertAllSearchHeaders(c, *all); err != nil {
		glog.Fatal(err)
	}

}
