// RemoveAllSeccompRules removes all seccomp syscall rules
func RemoveAllSeccompRules(config *rspec.Seccomp) error {
	if config == nil {
		return fmt.Errorf("Cannot remove action from nil Seccomp pointer")
	}
	newSyscallSlice := []rspec.Syscall{}
	config.Syscalls = newSyscallSlice
	return nil
}
// ParseDefaultActionForce simply sets the default action of the seccomp configuration
func ParseDefaultActionForce(action string, config *rspec.Seccomp) error {
	if action == "" {
		return nil
	}

	defaultAction, err := parseAction(action)
	if err != nil {
		return err
	}
	config.DefaultAction = defaultAction
	return nil
}
// ParseDefaultAction sets the default action of the seccomp configuration
// and then removes any rules that were already specified with this action
func ParseDefaultAction(action string, config *rspec.Seccomp) error {
	if action == "" {
		return nil
	}

	defaultAction, err := parseAction(action)
	if err != nil {
		return err
	}
	config.DefaultAction = defaultAction
	err = RemoveAllMatchingRules(config, action)
	if err != nil {
		return err
	}
	return nil
}
// ParseSyscallFlag takes a SyscallOpts struct and the seccomp configuration
// and sets the new syscall rule accordingly
func ParseSyscallFlag(args SyscallOpts, config *rspec.Seccomp) error {
	var arguments []string
	if args.Index != "" && args.Value != "" && args.ValueTwo != "" && args.Operator != "" {
		arguments = []string{args.Action, args.Syscall, args.Index, args.Value,
			args.ValueTwo, args.Operator}
	} else {
		arguments = []string{args.Action, args.Syscall}
	}

	action, _ := parseAction(arguments[0])
	if action == config.DefaultAction {
		return fmt.Errorf("default action already set as %s", action)
	}

	var newSyscall rspec.Syscall
	numOfArgs := len(arguments)
	if numOfArgs == 6 || numOfArgs == 2 {
		argStruct, err := parseArguments(arguments[1:])
		if err != nil {
			return err
		}
		newSyscall = newSyscallStruct(arguments[1], action, argStruct)
	} else {
		return fmt.Errorf("incorrect number of arguments to ParseSyscall: %d", numOfArgs)
	}

	descison, err := decideCourseOfAction(&newSyscall, config.Syscalls)
	if err != nil {
		return err
	}
	delimDescison := strings.Split(descison, ":")

	if delimDescison[0] == seccompAppend {
		config.Syscalls = append(config.Syscalls, newSyscall)
	}

	if delimDescison[0] == seccompOverwrite {
		indexForOverwrite, err := strconv.ParseInt(delimDescison[1], 10, 32)
		if err != nil {
			return err
		}
		config.Syscalls[indexForOverwrite] = newSyscall
	}

	return nil
}
// ParseArchitectureFlag takes the raw string passed with the --arch flag, parses it
// and updates the Seccomp config accordingly
func ParseArchitectureFlag(architectureArg string, config *rspec.Seccomp) error {
	correctedArch, err := parseArch(architectureArg)
	if err != nil {
		return err
	}

	shouldAppend := true
	for _, alreadySpecified := range config.Architectures {
		if correctedArch == alreadySpecified {
			shouldAppend = false
		}
	}
	if shouldAppend {
		config.Architectures = append(config.Architectures, correctedArch)
	}
	return nil
}
// RemoveAction takes the argument string that was passed with the --remove flag,
// parses it, and updates the Seccomp config accordingly
func RemoveAction(arguments string, config *rspec.Seccomp) error {
	if config == nil {
		return fmt.Errorf("Cannot remove action from nil Seccomp pointer")
	}

	var syscallsToRemove []string
	if strings.Contains(arguments, ",") {
		syscallsToRemove = strings.Split(arguments, ",")
	} else {
		syscallsToRemove = append(syscallsToRemove, arguments)
	}

	for _, syscall := range syscallsToRemove {
		for counter, syscallStruct := range config.Syscalls {
			if syscallStruct.Name == syscall {
				config.Syscalls = append(config.Syscalls[:counter], config.Syscalls[counter+1:]...)
			}
		}
	}
	return nil
}