<commit_before>package engine

import (
	"github.com/keybase/client/go/libkb"
	keybase1 "github.com/keybase/client/protocol/go"
)

type UntrackEngineArg struct {
	TheirName string
	Me        *libkb.User
}

type UntrackEngine struct {
	arg                   *UntrackEngineArg
	signingKeyPub         libkb.GenericKey
	untrackStatementBytes []byte
	libkb.Contextified
}

// NewUntrackEngine creates a default UntrackEngine for tracking theirName.
func NewUntrackEngine(arg *UntrackEngineArg, g *libkb.GlobalContext) *UntrackEngine {
	return &UntrackEngine{
		arg:          arg,
		Contextified: libkb.NewContextified(g),
	}
}

func (e *UntrackEngine) Name() string {
	return "Untrack"
}

func (e *UntrackEngine) GetPrereqs() EnginePrereqs {
	return EnginePrereqs{
		Session: true,
	}
}

func (e *UntrackEngine) RequiredUIs() []libkb.UIKind {
	return []libkb.UIKind{
		libkb.SecretUIKind,
	}
}

func (e *UntrackEngine) SubConsumers() []libkb.UIConsumer {
	return []libkb.UIConsumer{}
}

func (e *UntrackEngine) Run(ctx *Context) (err error) {
	e.arg.Me, err = e.loadMe()
	if err != nil {
		return
	}

	them, remoteLink, localLink, err := e.loadThem()
	if err != nil {
		return
	}

	e.signingKeyPub, err = e.arg.Me.SigningKeyPub()
	if err != nil {
		return
	}

	untrackStatement, err := e.arg.Me.UntrackingProofFor(e.signingKeyPub, them)
	if err != nil {
		return
	}

	e.untrackStatementBytes, err = untrackStatement.Marshal()
	if err != nil {
		return
	}

	e.G().Log.Debug("| Untracking statement: %s", string(e.untrackStatementBytes))

	didUntrack := false

	if localLink != nil {
		err = e.storeLocalUntrack(them)
		if err != nil {
			return
		}
		didUntrack = true
	}

	if remoteLink != nil && !remoteLink.IsRevoked() {
		err = e.storeRemoteUntrack(them, ctx)
		if err != nil {
			return
		}
		didUntrack = true
	}

	if !didUntrack {
		err = libkb.NewUntrackError("User @%s is already untracked", e.arg.TheirName)
		return
	}

	return
}

func (e *UntrackEngine) loadMe() (me *libkb.User, err error) {
	return libkb.LoadMe(libkb.LoadUserArg{})
}

func (e *UntrackEngine) loadThem() (them *libkb.User, remoteLink, localLink *libkb.TrackChainLink, err error) {
	var rLink *libkb.TrackChainLink
	trackMap := e.arg.Me.IDTable().GetTrackMap()
	if links, ok := trackMap[e.arg.TheirName]; ok && (len(links) > 0) {
		rLink = links[len(links)-1]
	}

	var uid keybase1.UID
	uidTrusted := false
	if rLink != nil {
		if uid, err = rLink.GetTrackedUid(); err != nil {
			return
		}
		uidTrusted = true
	}

	if uid.IsNil() {
		res := libkb.ResolveUid(e.arg.TheirName)
		if err = res.GetError(); err != nil {
			return
		}

		// This is an untrusted uid.
		uid = res.GetUID()
		if uid.IsNil() {
			err = libkb.NewUntrackError("Could not resolve uid for @%s", e.arg.TheirName)
			return
		}
	}

	lLink, err := libkb.GetLocalTrack(e.arg.Me.GetUID(), uid)
	if err != nil {
		return
	}

	if !uidTrusted {
		if lLink == nil {
			err = libkb.NewUntrackError("Could not verify resolved uid for @%s", e.arg.TheirName)
			return
		}

		var trackedUsername string<commit_msg>Closed #428<commit_after>package engine

import (
	"github.com/keybase/client/go/libkb"
	keybase1 "github.com/keybase/client/protocol/go"
)

type UntrackEngineArg struct {
	TheirName string
	Me        *libkb.User
}

type UntrackEngine struct {
	arg                   *UntrackEngineArg
	signingKeyPub         libkb.GenericKey
	untrackStatementBytes []byte
	libkb.Contextified
}

// NewUntrackEngine creates a default UntrackEngine for tracking theirName.
func NewUntrackEngine(arg *UntrackEngineArg, g *libkb.GlobalContext) *UntrackEngine {
	return &UntrackEngine{
		arg:          arg,
		Contextified: libkb.NewContextified(g),
	}
}

func (e *UntrackEngine) Name() string {
	return "Untrack"
}

func (e *UntrackEngine) GetPrereqs() EnginePrereqs {
	return EnginePrereqs{
		Session: true,
	}
}

func (e *UntrackEngine) RequiredUIs() []libkb.UIKind {
	return []libkb.UIKind{
		libkb.SecretUIKind,
	}
}

func (e *UntrackEngine) SubConsumers() []libkb.UIConsumer {
	return []libkb.UIConsumer{}
}

func (e *UntrackEngine) Run(ctx *Context) (err error) {
	e.arg.Me, err = e.loadMe()
	if err != nil {
		return
	}

	them, remoteLink, localLink, err := e.loadThem()
	if err != nil {
		return
	}

	e.signingKeyPub, err = e.arg.Me.SigningKeyPub()
	if err != nil {
		return
	}

	untrackStatement, err := e.arg.Me.UntrackingProofFor(e.signingKeyPub, them)
	if err != nil {
		return
	}

	e.untrackStatementBytes, err = untrackStatement.Marshal()
	if err != nil {
		return
	}

	e.G().Log.Debug("| Untracking statement: %s", string(e.untrackStatementBytes))

	didUntrack := false

	if localLink != nil {
		err = e.storeLocalUntrack(them)
		if err != nil {
			return
		}
		didUntrack = true
	}

	if remoteLink != nil && !remoteLink.IsRevoked() {
		err = e.storeRemoteUntrack(them, ctx)
		if err != nil {
			return
		}
		didUntrack = true
	}

	if !didUntrack {
		err = libkb.NewUntrackError("User @%s is already untracked", e.arg.TheirName)
		return
	}

	return
}

func (e *UntrackEngine) loadMe() (me *libkb.User, err error) {
	return libkb.LoadMe(libkb.LoadUserArg{})
}

func (e *UntrackEngine) loadThem() (them *libkb.User, remoteLink, localLink *libkb.TrackChainLink, err error) {
	var rLink *libkb.TrackChainLink
	trackMap := e.arg.Me.IDTable().GetTrackMap()
	if links, ok := trackMap[e.arg.TheirName]; ok && (len(links) > 0) {
		rLink = links[len(links)-1]
	}

	var uid keybase1.UID
	uidTrusted := false
	if rLink != nil {
		if uid, err = rLink.GetTrackedUid(); err != nil {
			return
		}
		uidTrusted = true
	}

	if uid.IsNil() {
		res := libkb.ResolveUid(e.arg.TheirName)
		if err = res.GetError(); err != nil {
			return
		}

		// This is an untrusted uid.
		uid = res.GetUID()
		if uid.IsNil() {
			err = libkb.NewUntrackError("Could not resolve uid for @%s", e.arg.TheirName)
			return
		}
	}

	lLink, err := libkb.GetLocalTrack(e.arg.Me.GetUID(), uid)
	if err != nil {
		return
	}

	if rLink == nil && lLink == nil {
		err = libkb.NewUntrackError("You are not tracking %s", e.arg.TheirName)
		return
	}

	if !uidTrusted {
		if lLink == nil {
			err = libkb.NewUntrackError("Could not verify resolved uid for @%s", e.arg.TheirName)
			return
		}

		var trackedUsername string
{'fraction_non_alphanumeric': 0.13212101705825555, 'fraction_numerical': 0.001770196330865787, 'mean_word_length': 3.553113553113553, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '6571468', 'n_tokens_mistral': 2483, 'n_tokens_neox': 2319, 'n_words': 547}