<commit_before>package main

import (
	"encoding/base64"
	"errors"
	"fmt"
	"os"
	"path/filepath"

	cmds "github.com/jbenet/go-ipfs/commands"
	config "github.com/jbenet/go-ipfs/config"
	ci "github.com/jbenet/go-ipfs/crypto"
	peer "github.com/jbenet/go-ipfs/peer"
	updates "github.com/jbenet/go-ipfs/updates"
	u "github.com/jbenet/go-ipfs/util"
)

var initCmd = &cmds.Command{
	Options: []cmds.Option{
		cmds.Option{[]string{"bits", "b"}, cmds.Int},
		cmds.Option{[]string{"passphrase", "p"}, cmds.String},
		cmds.Option{[]string{"force", "f"}, cmds.Bool},
		cmds.Option{[]string{"datastore", "d"}, cmds.String},
	},
	Help: `ipfs init

	Initializes ipfs configuration files and generates a
	new keypair.
	`,
	Run: func(res cmds.Response, req cmds.Request) {

		arg, found := req.Option("d")
		dspath, ok := arg.(string)
		if found && !ok {
			res.SetError(errors.New("failed to parse datastore flag"), cmds.ErrNormal)
			return
		}

		arg, found = req.Option("f")
		force, ok := arg.(bool) // TODO param
		if found && !ok {
			res.SetError(errors.New("failed to parse force flag"), cmds.ErrNormal)
			return
		}

		arg, found = req.Option("b")
		nBitsForKeypair, ok := arg.(int) // TODO param
		if found && !ok {
			res.SetError(errors.New("failed to get bits flag"), cmds.ErrNormal)
			return
		} else if !found {
			nBitsForKeypair = 4096
		}

		err := doInit(req.Context().ConfigRoot, dspath, force, nBitsForKeypair)
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
	},
}

// Use these hardcoded bootstrap peers for now.
var defaultPeers = []*config.BootstrapPeer{
	&config.BootstrapPeer{
		// mars.i.ipfs.io
		PeerID:  "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
		Address: "/ip4/172.16.58.3/tcp/4001",
	},
}

func doInit(configRoot string, dspath string, force bool, nBitsForKeypair int) error {

	u.POut("initializing ipfs node at %s\n", configRoot)

	configFilename, err := config.Filename(configRoot)
	if err != nil {
		return errors.New("Couldn't get home directory path")
	}

	fi, err := os.Lstat(configFilename)
	if fi != nil || (err != nil && !os.IsNotExist(err)) {
		if !force {
			// TODO multi-line string
			return errors.New("ipfs configuration file already exists!\nReinitializing would overwrite your keys.\n(use -f to force overwrite)")
		}
	}

	ds, err := datastoreConfig(dspath)
	if err != nil {
		return err
	}

	identity, err := identityConfig(nBitsForKeypair)
	if err != nil {
		return err
	}

	conf := config.Config{

		// setup the node addresses.
		Addresses: config.Addresses{
			Swarm: "/ip4/0.0.0.0/tcp/4001",
			API:   "/ip4/127.0.0.1/tcp/5001",
		},

		Bootstrap: defaultPeers,

		Datastore: ds,

		Identity: identity,

		// setup the node mount points.
		Mounts: config.Mounts{
			IPFS: "/ipfs",
			IPNS: "/ipns",
		},

		// tracking ipfs version used to generate the init folder and adding
		// update checker default setting.
		Version: config.Version{
			Check:   "error",
			Current: updates.Version,
		},
	}

	err = config.WriteConfigFile(configFilename, conf)
	if err != nil {
		return err
	}
	return nil
}

func datastoreConfig(dspath string) (config.Datastore, error) {
	ds := config.Datastore{}
	if len(dspath) == 0 {
		var err error
		dspath, err = config.DataStorePath("")
		if err != nil {
			return ds, err
		}
	}
	ds.Path = dspath
	ds.Type = "leveldb"

	// Construct the data store if missing
	if err := os.MkdirAll(dspath, os.ModePerm); err != nil {
		return ds, err
	}<commit_msg>TODO(ipfs2/init) add FIXME note as a reminder about<commit_after>package main

import (
	"encoding/base64"
	"errors"
	"fmt"
	"os"
	"path/filepath"

	cmds "github.com/jbenet/go-ipfs/commands"
	config "github.com/jbenet/go-ipfs/config"
	ci "github.com/jbenet/go-ipfs/crypto"
	peer "github.com/jbenet/go-ipfs/peer"
	updates "github.com/jbenet/go-ipfs/updates"
	u "github.com/jbenet/go-ipfs/util"
)

var initCmd = &cmds.Command{
	Options: []cmds.Option{
		cmds.Option{[]string{"bits", "b"}, cmds.Int},
		cmds.Option{[]string{"passphrase", "p"}, cmds.String},
		cmds.Option{[]string{"force", "f"}, cmds.Bool},
		cmds.Option{[]string{"datastore", "d"}, cmds.String},
	},
	Help: `ipfs init

	Initializes ipfs configuration files and generates a
	new keypair.
	`,
	Run: func(res cmds.Response, req cmds.Request) {

		arg, found := req.Option("d")
		dspath, ok := arg.(string)
		if found && !ok {
			res.SetError(errors.New("failed to parse datastore flag"), cmds.ErrNormal)
			return
		}

		arg, found = req.Option("f")
		force, ok := arg.(bool) // TODO param
		if found && !ok {
			res.SetError(errors.New("failed to parse force flag"), cmds.ErrNormal)
			return
		}

		arg, found = req.Option("b")
		nBitsForKeypair, ok := arg.(int) // TODO param
		if found && !ok {
			res.SetError(errors.New("failed to get bits flag"), cmds.ErrNormal)
			return
		} else if !found {
			nBitsForKeypair = 4096
		}

		err := doInit(req.Context().ConfigRoot, dspath, force, nBitsForKeypair)
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
	},
}

// Use these hardcoded bootstrap peers for now.
var defaultPeers = []*config.BootstrapPeer{
	&config.BootstrapPeer{
		// mars.i.ipfs.io
		PeerID:  "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
		Address: "/ip4/172.16.58.3/tcp/4001",
	},
}

func doInit(configRoot string, dspath string, force bool, nBitsForKeypair int) error {

	u.POut("initializing ipfs node at %s\n", configRoot)

	configFilename, err := config.Filename(configRoot)
	if err != nil {
		return errors.New("Couldn't get home directory path")
	}

	fi, err := os.Lstat(configFilename)
	if fi != nil || (err != nil && !os.IsNotExist(err)) {
		if !force {
			// TODO multi-line string
			return errors.New("ipfs configuration file already exists!\nReinitializing would overwrite your keys.\n(use -f to force overwrite)")
		}
	}

	ds, err := datastoreConfig(dspath)
	if err != nil {
		return err
	}

	identity, err := identityConfig(nBitsForKeypair)
	if err != nil {
		return err
	}

	conf := config.Config{

		// setup the node addresses.
		Addresses: config.Addresses{
			Swarm: "/ip4/0.0.0.0/tcp/4001",
			API:   "/ip4/127.0.0.1/tcp/5001",
		},

		Bootstrap: defaultPeers,

		Datastore: ds,

		Identity: identity,

		// setup the node mount points.
		Mounts: config.Mounts{
			IPFS: "/ipfs",
			IPNS: "/ipns",
		},

		// tracking ipfs version used to generate the init folder and adding
		// update checker default setting.

		// FIXME(brian): before merging into master, change this to...
		// Version: config.VersionDefaultValue()
		Version: config.Version{
			Check:   "error",
			Current: updates.Version,
		},
	}

	err = config.WriteConfigFile(configFilename, conf)
	if err != nil {
		return err
	}
	return nil
}

func datastoreConfig(dspath string) (config.Datastore, error) {
	ds := config.Datastore{}
	if len(dspath) == 0 {
		var err error
		dspath, err = config.DataStorePath("")
		if err != nil {
			return ds, err
		}
	}
	ds.Path = dspath
	ds.Type = "leveldb"

	// Construct the data store if missing
	if err := os.MkdirAll(dspath, os.ModePerm); err != nil {
		return ds, err
	}
{'fraction_non_alphanumeric': 0.1493975903614458, 'fraction_numerical': 0.012331679659815733, 'mean_word_length': 3.5, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 6, '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': '5170322', 'n_tokens_mistral': 2920, 'n_tokens_neox': 2654, 'n_words': 639}