package jira

import (
	"database/sql/driver"
	"encoding/json"
	"fmt"
	"strings"
	"time"

	"github.com/andygrunwald/go-jira"
)

const (
	TimeLayout = "2006-01-02T15:04:05.000+0000"
)

type RawIssue jira.Issue

// read IssueExtraData of json string format from database
func (a *RawIssue) Scan(value interface{}) error {
	bytes, ok := value.([]byte)
	if !ok {
		return fmt.Errorf("unsupported value: %v", value)
	}

	result := RawIssue{}

	err := json.Unmarshal(bytes, &result)
	*a = result
	return err
}

// store IssueExtraData as json string in database
func (a RawIssue) Value() (driver.Value, error) {
	b, err := json.Marshal(a)
	if err != nil {
		return nil, err
	}
	s := string(b)
	return s, err
}

type Issue struct {
	Key             string    `gorm:"primaryKey;type:varchar(255)"`
	Url             string    `gorm:"type:varchar(255)"`
	ReporterEmail   string    `gorm:"type:varchar(255)"`
	AssigneeEmail   string    `gorm:"type:varchar(255)"`
	Component       string    `gorm:"type:varchar(255)"`
	Priority        string    `gorm:"type:varchar(64)"`
	Status          string    `gorm:"type:varchar(64)"`
	Summary         string    `gorm:"type:varchar(255)"`
	Description     string    `gorm:"type:text"`
	CreateTime      time.Time `gorm:"type:timestamp"`
	RawIssue        RawIssue  `gorm:"type:longtext"`
	ReceivedVersion int64
}

type Issues []Issue

// convert andygrunwald's go-jira Issue to jiraport's Issue
func FromGoJiraIssue(jiraIssue *jira.Issue) (*Issue, error) {
	fields := jiraIssue.Fields
	component := make([]string, 0, len(fields.Components))
	for i := range fields.Components {
		component = append(component, fields.Components[i].Name)
	}
	component_str := strings.Join(component, ",")
	return &Issue{
		Key:           jiraIssue.Key,
		Url:           jiraIssue.Self,
		Summary:       fields.Summary,
		Description:   fields.Description,
		ReporterEmail: fields.Reporter.EmailAddress,
		AssigneeEmail: fields.Assignee.EmailAddress,
		Component:     component_str,
		Priority:      fields.Priority.Name,
		Status:        fields.Status.Name,
		CreateTime:    time.Time(fields.Created),
		RawIssue:      RawIssue(*jiraIssue),
	}, nil
}
