<commit_before>package utils

import (
	"crypto/x509"
	"encoding/pem"
	"encoding/xml"
	"fmt"
	log "github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
	"github.com/mitchellh/go-homedir"
	"io/ioutil"
	"net/url"
	"os"
	"os/user"
	"path"
	"path/filepath"
	"runtime"
	"strings"
)

const windowsServerConfigFile = "c:\\concerto\\client.xml"
const nixServerConfigFile = "/etc/concerto/client.xml"

// Config stores configuration file contents
type Config struct {
	XMLName      xml.Name `xml:"concerto"`
	APIEndpoint  string   `xml:"server,attr"`
	LogFile      string   `xml:"log_file,attr"`
	LogLevel     string   `xml:"log_level,attr"`
	Certificate  Cert     `xml:"ssl"`
	ConfLocation string
	ConfFile     string
	IsHost       bool
	ConcertoURL  string
}

// Cert stores cert files location
type Cert struct {
	Cert string `xml:"cert,attr"`
	Key  string `xml:"key,attr"`
	Ca   string `xml:"server_ca,attr"`
}

var cachedConfig *Config

// GetConcertoConfig returns concerto configuration
func GetConcertoConfig() (*Config, error) {
	if cachedConfig == nil {
		return nil, fmt.Errorf("Configuration hasn't been initialized")
	}
	return cachedConfig, nil
}

// InitializeConcertoConfig creates the concerto configuration structure
func InitializeConcertoConfig(c *cli.Context) (*Config, error) {
	log.Debug("InitializeConcertoConfig")
	if cachedConfig != nil {
		return cachedConfig, nil
	}

	// where config file must me
	cachedConfig = &Config{}
	err := cachedConfig.evaluateConcertoConfigFile(c)
	if err != nil {
		return nil, err
	}

	// read config contents
	log.Debugf("Reading configuration from %s", cachedConfig.ConfFile)
	err = cachedConfig.readConcertoConfig(c)
	if err != nil {
		return nil, err
	}

	// add login URL. Needed for setup
	err = cachedConfig.readConcertoURL()
	if err != nil {
		return nil, err
	}

	// check if isHost. Needed to show appropiate options
	err = cachedConfig.evaluateCertificate()
	if err != nil {
		return nil, err
	}

	log.Debugf("Concerto configuration used: %+v", cachedConfig)
	return cachedConfig, nil
}

// IsConfigReady returns whether configurations items are filled
func (config *Config) IsConfigReady() bool {
	if config.APIEndpoint == "" ||
		config.Certificate.Cert == "" ||
		config.Certificate.Key == "" ||
		config.Certificate.Ca == "" {
		return false
	}
	return true
}

// IsConfigReadySetup returns whether we can use setup command
func (config *Config) IsConfigReadySetup() bool {
	return config.ConcertoURL != ""
}

// readConcertoConfig reads Concerto config file located at fileLocation
func (config *Config) readConcertoConfig(c *cli.Context) error {
	log.Debug("Reading Concerto Configuration")
	if FileExists(config.ConfFile) {
		// file exists, read it's contents

		xmlFile, err := os.Open(config.ConfFile)
		if err != nil {
			return err
		}
		defer xmlFile.Close()
		b, err := ioutil.ReadAll(xmlFile)
		if err != nil {
			return fmt.Errorf("Configuration File %s couldn't be read.", config.ConfFile)
		}

		if err = xml.Unmarshal(b, &config); err != nil {
			return fmt.Errorf("Configuration File %s does not have valid XML format.", config.ConfFile)
		}

	} else {
		log.Debugf("Configuration File %s does not exist. Reading environment variables", config.ConfFile)
	}

	// overwrite with environment/arguments vars
	if overwEP := c.String("concerto-endpoint"); overwEP != "" {
		log.Debug("Concerto APIEndpoint taken from env/args")
		config.APIEndpoint = overwEP
	}

	if overwCert := c.String("client-cert"); overwCert != "" {
		log.Debug("Certificate path taken from env/args")
		config.Certificate.Cert = overwCert
	}

	if overwKey := c.String("client-key"); overwKey != "" {
		log.Debug("Certificate key path taken from env/args")
		config.Certificate.Key = overwKey
	}

	if overwCa := c.String("ca-cert"); overwCa != "" {
		log.Debug("CA certificate path taken from env/args")
		config.Certificate.Ca = overwCa
	}

	return nil
}

// evaluateConcertoConfigFile returns path to concerto config file
func (config *Config) evaluateConcertoConfigFile(c *cli.Context) error {

	if configFile := c.String("concerto-config"); configFile != "" {

		log.Debug("Concerto configuration file location taken from env/args")
		config.ConfFile = configFile

	} else {

		currUser, err := user.Current()
		if err != nil {
			log.Debugf("Couldn't use os.user to get user details: %s", err.Error())
			dir, err := homedir.Dir()
			if err != nil {
				return fmt.Errorf("Couldn't get home dir for current user: %s", err.Error())
			}
			currUser = &user.User{<commit_msg>add default endpoint url in case a user is executing setup, but no conf file is present, assume production<commit_after>package utils

import (
	"crypto/x509"
	"encoding/pem"
	"encoding/xml"
	"fmt"
	log "github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
	"github.com/mitchellh/go-homedir"
	"io/ioutil"
	"net/url"
	"os"
	"os/user"
	"path"
	"path/filepath"
	"runtime"
	"strings"
)

const windowsServerConfigFile = "c:\\concerto\\client.xml"
const nixServerConfigFile = "/etc/concerto/client.xml"
const defaultConcertoEndpoint = "https://clients.concerto.io:886/"

// Config stores configuration file contents
type Config struct {
	XMLName      xml.Name `xml:"concerto"`
	APIEndpoint  string   `xml:"server,attr"`
	LogFile      string   `xml:"log_file,attr"`
	LogLevel     string   `xml:"log_level,attr"`
	Certificate  Cert     `xml:"ssl"`
	ConfLocation string
	ConfFile     string
	IsHost       bool
	ConcertoURL  string
}

// Cert stores cert files location
type Cert struct {
	Cert string `xml:"cert,attr"`
	Key  string `xml:"key,attr"`
	Ca   string `xml:"server_ca,attr"`
}

var cachedConfig *Config

// GetConcertoConfig returns concerto configuration
func GetConcertoConfig() (*Config, error) {
	if cachedConfig == nil {
		return nil, fmt.Errorf("Configuration hasn't been initialized")
	}
	return cachedConfig, nil
}

// InitializeConcertoConfig creates the concerto configuration structure
func InitializeConcertoConfig(c *cli.Context) (*Config, error) {
	log.Debug("InitializeConcertoConfig")
	if cachedConfig != nil {
		return cachedConfig, nil
	}

	// where config file must me
	cachedConfig = &Config{}
	err := cachedConfig.evaluateConcertoConfigFile(c)
	if err != nil {
		return nil, err
	}

	// read config contents
	log.Debugf("Reading configuration from %s", cachedConfig.ConfFile)
	err = cachedConfig.readConcertoConfig(c)
	if err != nil {
		return nil, err
	}

	// add login URL. Needed for setup
	err = cachedConfig.readConcertoURL()
	if err != nil {
		return nil, err
	}

	// check if isHost. Needed to show appropiate options
	err = cachedConfig.evaluateCertificate()
	if err != nil {
		return nil, err
	}

	log.Debugf("Concerto configuration used: %+v", cachedConfig)
	return cachedConfig, nil
}

// IsConfigReady returns whether configurations items are filled
func (config *Config) IsConfigReady() bool {
	if config.APIEndpoint == "" ||
		config.Certificate.Cert == "" ||
		config.Certificate.Key == "" ||
		config.Certificate.Ca == "" {
		return false
	}
	return true
}

// IsConfigReadySetup returns whether we can use setup command
func (config *Config) IsConfigReadySetup() bool {
	return config.ConcertoURL != ""
}

// readConcertoConfig reads Concerto config file located at fileLocation
func (config *Config) readConcertoConfig(c *cli.Context) error {
	log.Debug("Reading Concerto Configuration")
	if FileExists(config.ConfFile) {
		// file exists, read it's contents

		xmlFile, err := os.Open(config.ConfFile)
		if err != nil {
			return err
		}
		defer xmlFile.Close()
		b, err := ioutil.ReadAll(xmlFile)
		if err != nil {
			return fmt.Errorf("Configuration File %s couldn't be read.", config.ConfFile)
		}

		if err = xml.Unmarshal(b, &config); err != nil {
			return fmt.Errorf("Configuration File %s does not have valid XML format.", config.ConfFile)
		}

	} else {
		log.Debugf("Configuration File %s does not exist. Reading environment variables", config.ConfFile)
	}

	// overwrite with environment/arguments vars
	if overwEP := c.String("concerto-endpoint"); overwEP != "" {
		log.Debug("Concerto APIEndpoint taken from env/args")
		config.APIEndpoint = overwEP
	}

	if overwCert := c.String("client-cert"); overwCert != "" {
		log.Debug("Certificate path taken from env/args")
		config.Certificate.Cert = overwCert
	}

	if overwKey := c.String("client-key"); overwKey != "" {
		log.Debug("Certificate key path taken from env/args")
		config.Certificate.Key = overwKey
	}

	if overwCa := c.String("ca-cert"); overwCa != "" {
		log.Debug("CA certificate path taken from env/args")
		config.Certificate.Ca = overwCa
	}

	// if endpoint empty set default
	// we can't set the default from flags, because it would overwrite config file
	if config.APIEndpoint == "" {
		config.APIEndpoint = defaultConcertoEndpoint
	}

	return nil
}

// evaluateConcertoConfigFile returns path to concerto config file
func (config *Config) evaluateConcertoConfigFile(c *cli.Context) error {

	if configFile := c.String("concerto-config"); configFile != "" {

		log.Debug("Concerto configuration file location taken from env/args")
		config.ConfFile = configFile

	} else {

		currUser, err := user.Current()
		if err != nil {
			log.Debugf("Couldn't use os.user to get user details: %s", err.Error())
			dir, err := homedir.Dir()
			if err != nil {
				return fmt.Errorf("Couldn't get home dir for current user: %s", err.Error())
			}
			currUser = &user.User{
{'fraction_non_alphanumeric': 0.12205226258763544, 'fraction_numerical': 0.0009560229445506692, 'mean_word_length': 4.050965665236052, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 32}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1597584', 'n_tokens_mistral': 3179, 'n_tokens_neox': 2995, 'n_words': 856}