summaryrefslogtreecommitdiff
path: root/main.go
blob: d8adf3a43b8026ccb54f752f0e429b2d23035a55 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package main

import (
	"encoding/csv"
	"errors"
	"fmt"
	"log"
	"os"
	"strings"
	"time"

	"github.com/jszwec/csvutil"
)

type Participant struct {
	LastName    string `csv:"lastname"`
	FirstName   string `csv:"firstname"`
	DateOfBirth string `csv:"dateofbirth"`
	Gender      Gender `csv:"gender"`
	Nation      string `csv:"nation"`
	Region      string `csv:"region"`
	ClubStr     string `csv:"club"`
	Id          uint   `csv:"-"`
	ClubId      uint   `csv:"-"`
}

type Club struct {
	Name string
	Id   uint
}

func prepareParticipants(participants []Participant) []Club {
	clubMap := map[string]uint{}
	var clubs []Club
	var clubId, participantId uint

	for i := range participants {
		p := &participants[i]
		participantId++

		p.Id = participantId

		pClub := p.ClubStr
		if strings.Contains(pClub, ", ") {
			pClub = strings.Split(pClub, ", ")[0]
		}

		if cId, ok := clubMap[pClub]; ok {
			p.ClubId = cId
		} else {
			clubId++

			p.ClubId = clubId
			clubMap[pClub] = clubId
			clubs = append(clubs, Club{pClub, clubId})
		}
	}

	return clubs
}

func parseOphardtInput(fileName string) ([]Participant, []Club, error) {
	f, err := os.Open(fileName)
	if err != nil {
		return nil, nil, fmt.Errorf("opening input file '%s': %w", fileName, err)
	}

	encReader, err := encodedReader(f)
	if err != nil {
		return nil, nil, fmt.Errorf("cannot determine encoding of file '%s': %w", fileName, err)
	}

	csvReader := csv.NewReader(encReader)
	csvReader.Comma = ';'

	dec, err := csvutil.NewDecoder(csvReader)
	if err != nil {
		return nil, nil, fmt.Errorf("reading from file '%s': %w", fileName, err)
	}
	dec.DisallowMissingColumns = true

	var participants []Participant
	if err = dec.Decode(&participants); err != nil {
		return nil, nil, fmt.Errorf("decoding file '%s': %w", fileName, err)
	}

	clubs := prepareParticipants(participants)
	return participants, clubs, nil
}

func usage() string {
	return fmt.Sprintf("Usage: %s <input csv> <output dir> <name> <M/F> <S/V> <D/F/S> <dd.mm.yyyy>", os.Args[0])
}

type EngardeConfig struct {
	inputFile    string
	outputDir    string
	Name         string
	Description  string
	Gender       Gender
	AgeGroup     AgeGroup
	Weapon       Weapon
	Date         time.Time
	Participants []Participant
	Clubs        []Club
}

func parseArgs() (config EngardeConfig, err error) {
	config.inputFile = os.Args[1]
	config.outputDir = os.Args[2]
	config.Name = os.Args[3]

	if config.Gender, err = GenderFromString(os.Args[4]); err != nil {
		return EngardeConfig{}, err
	}
	if config.AgeGroup, err = AgeGroupFromString(os.Args[5]); err != nil {
		return EngardeConfig{}, err
	}
	if config.Weapon, err = WeaponFromString(os.Args[6]); err != nil {
		return EngardeConfig{}, err
	}

	if config.Date, err = time.Parse("02.01.2006", os.Args[7]); err != nil {
		return EngardeConfig{}, err
	}

	return config, nil
}

func run() error {
	if len(os.Args) <= 7 {
		return errors.New(usage())
	}

	cfg, err := parseArgs()
	if err != nil {
		return err
	}

	cfg.Participants, cfg.Clubs, err = parseOphardtInput(cfg.inputFile)
	if err != nil {
		return err
	}

	return write(cfg)
}

func main() {
	if err := run(); err != nil {
		log.Fatalf("An error occured: %v", err)
	}
}