// +build !scanner

package exploit

import (
	"encoding/json"

	"github.com/future-architect/vuls/config"
	"github.com/future-architect/vuls/models"
	"github.com/future-architect/vuls/util"
	"github.com/vulsio/go-exploitdb/db"
	exploitmodels "github.com/vulsio/go-exploitdb/models"
)

// FillWithExploit fills exploit information that has in Exploit
func FillWithExploit(driver db.DB, r *models.ScanResult, cnf *config.ExploitConf) (nExploitCve int, err error) {
	if cnf.IsFetchViaHTTP() {
		var cveIDs []string
		for cveID := range r.ScannedCves {
			cveIDs = append(cveIDs, cveID)
		}
		prefix, _ := util.URLPathJoin(cnf.URL, "cves")
		responses, err := getCvesViaHTTP(cveIDs, prefix)
		if err != nil {
			return 0, err
		}
		for _, res := range responses {
			exps := []*exploitmodels.Exploit{}
			if err := json.Unmarshal([]byte(res.json), &exps); err != nil {
				return 0, err
			}
			exploits := ConvertToModels(exps)
			v, ok := r.ScannedCves[res.request.cveID]
			if ok {
				v.Exploits = exploits
			}
			r.ScannedCves[res.request.cveID] = v
			nExploitCve++
		}
	} else {
		if driver == nil {
			return 0, nil
		}
		for cveID, vuln := range r.ScannedCves {
			if cveID == "" {
				continue
			}
			es := driver.GetExploitByCveID(cveID)
			if len(es) == 0 {
				continue
			}
			exploits := ConvertToModels(es)
			vuln.Exploits = exploits
			r.ScannedCves[cveID] = vuln
			nExploitCve++
		}
	}
	return nExploitCve, nil
}

// ConvertToModels converts gost model to vuls model
func ConvertToModels(es []*exploitmodels.Exploit) (exploits []models.Exploit) {
	for _, e := range es {
		var documentURL, shellURL *string
		if e.OffensiveSecurity != nil {
			os := e.OffensiveSecurity
			if os.Document != nil {
				documentURL = &os.Document.DocumentURL
			}
			if os.ShellCode != nil {
				shellURL = &os.ShellCode.ShellCodeURL
			}
		}
		exploit := models.Exploit{
			ExploitType:  e.ExploitType,
			ID:           e.ExploitUniqueID,
			URL:          e.URL,
			Description:  e.Description,
			DocumentURL:  documentURL,
			ShellCodeURL: shellURL,
		}
		exploits = append(exploits, exploit)
	}
	return exploits
}
