package datamysql

import (
	"database/sql"

	"bitbucket.org/nemt/nemt-portal-api/domain/entity"
	"bitbucket.org/nemt/nemt-portal-api/infra/errors"
)

// rideRepo maps methods to database
type profileRepo struct {
	conn executor
}

func newProfileRepo(conn executor) *profileRepo {
	return &profileRepo{
		conn: conn,
	}
}

func (c *profileRepo) getQuery() string {
	const (
		query = `SELECT 
										a.profile_id,
										a.name,
										a.key,
										a.description,
										a.create_time,
										a.update_time,
										(a.active = b'1') active,
										(a.visible = b'1') visible
							FROM
										tab_profile a `
	)

	return query
}

// parseSet parses a result set result to an entity array
func (c *profileRepo) parseSet(rows *sql.Rows, err error) ([]entity.Profile, error) {
	if err != nil {
		return nil, errors.Wrap(err)
	}
	result := make([]entity.Profile, 0)
	for rows.Next() {
		entity, err := c.parseEntity(rows)
		if err != nil {
			return nil, errors.Wrap(err)
		}
		result = append(result, entity)
	}
	return result, nil
}

// parseEntity parses a result to an entity
func (c *profileRepo) parseEntity(row scanner) (retVal entity.Profile, err error) {
	err = row.Scan(
		&retVal.ID, &retVal.Name, &retVal.Key, &retVal.Description, &retVal.Created, &retVal.Updated, &retVal.Active, &retVal.Visible)

	return retVal, errors.Wrap(err)
}

func (c *profileRepo) GetAll() ([]entity.Profile, error) {
	return c.parseSet(c.conn.Query(c.getQuery()))
}

func (c *profileRepo) GetByKey(key string) (entity.Profile, error) {
	return c.parseEntity(c.conn.QueryRow(c.getQuery()+"WHERE a.active = 1 AND a.key = ?", key))
}

func (c *profileRepo) GetVisibles(visible bool) ([]entity.Profile, error) {
	return c.parseSet(c.conn.Query(c.getQuery()+"WHERE a.active = 1 AND a.visible = ?", visible))
}

func (c *profileRepo) GetByOrganizationType(organizationTypeID int64) ([]entity.Profile, error) {
	return c.parseSet(c.conn.Query(c.getQuery()+" INNER JOIN tab_organization_type_profile b ON a.profile_id = b.profile_id WHERE a.active = 1 AND a.visible = 1 AND b.organization_type_id = ?", organizationTypeID))
}
