// DeepCopy makes a complete copy of this file, deduping leaf blocks
// and making new random BlockPointers for all indirect blocks.  It
// returns the new top pointer of the copy, and all the new child
// pointers in the copy.
435390
func (fd *FileData) DeepCopy(ctx context.Context, dataVer Ver) (
	newTopPtr BlockPointer, allChildPtrs []BlockPointer, err error) {
	topBlock, _, err := fd.getter(ctx, fd.tree.kmd, fd.rootBlockPointer(),
		fd.tree.file, BlockRead)
	if err != nil {
		return ZeroPtr, nil, err
	}

	// Handle the single-level case first.
	if !topBlock.IsInd {
		newTopBlock := topBlock.DeepCopy()
		if err != nil {
			return ZeroPtr, nil, err
		}

		newTopPtr = fd.rootBlockPointer()
		newTopPtr.RefNonce, err = kbfsblock.MakeRefNonce()
		if err != nil {
			return ZeroPtr, nil, err
		}
		newTopPtr.SetWriter(fd.tree.chargedTo)

		if err = fd.tree.cacher(ctx, newTopPtr, newTopBlock); err != nil {
			return ZeroPtr, nil, err
		}

		fd.tree.vlog.CLogf(
			ctx, libkb.VLog1, "Deep copied file %s: %v -> %v",
			fd.tree.file.TailName(), fd.rootBlockPointer(), newTopPtr)

		return newTopPtr, nil, nil
	}

	// For indirect files, get all the paths to leaf blocks.
	pfr, err := fd.tree.getIndirectBlocksForOffsetRange(
		ctx, topBlock, Int64Offset(0), nil)
	if err != nil {
		return ZeroPtr, nil, err
	}
	if len(pfr) == 0 {
		return ZeroPtr, nil,
			fmt.Errorf("Indirect file %v had no indirect blocks",
				fd.rootBlockPointer())
	}

	// Make a new reference for all leaf blocks first.
	copiedBlocks := make(map[BlockPointer]*FileBlock)
	leafLevel := len(pfr[0]) - 1
	for level := leafLevel; level >= 0; level-- {
		for _, Path := range pfr {
			// What is the current ptr for this pblock?
			ptr := fd.rootBlockPointer()
			if level > 0 {
				ptr = Path[level-1].childBlockPtr()
			}
			if _, ok := copiedBlocks[ptr]; ok {
				continue
			}

			// Copy the parent block and save it for later (it will be
			// cached below).
			pblock := Path[level].pblock.(*FileBlock).DeepCopy()
			if err != nil {
				return ZeroPtr, nil, err
			}
			copiedBlocks[ptr] = pblock

			for i, iptr := range pblock.IPtrs {
				if level == leafLevel {
					// Generate a new nonce for each indirect pointer
					// to a leaf.
					iptr.RefNonce, err = kbfsblock.MakeRefNonce()
					if err != nil {
						return ZeroPtr, nil, err
					}
					iptr.SetWriter(fd.tree.chargedTo)
					pblock.IPtrs[i] = iptr
					allChildPtrs = append(allChildPtrs, iptr.BlockPointer)
				} else {
					// Generate a new random ID for each indirect
					// pointer to an indirect block.
					newID, err := kbfsblock.MakeTemporaryID()
					if err != nil {
						return ZeroPtr, nil, err
					}
					// No need for a new refnonce here, since indirect
					// blocks are guaranteed to get a new block ID
					// when readied, since the child block pointers
					// will have changed.
					newPtr := BlockPointer{
						ID:      newID,
						KeyGen:  fd.tree.kmd.LatestKeyGeneration(),
						DataVer: dataVer,
						Context: kbfsblock.MakeFirstContext(
							fd.tree.chargedTo,
							fd.rootBlockPointer().GetBlockType()),
						DirectType: IndirectBlock,
					}
					pblock.IPtrs[i].BlockPointer = newPtr
					allChildPtrs = append(allChildPtrs, newPtr)
					childBlock, ok := copiedBlocks[iptr.BlockPointer]
					if !ok {
						return ZeroPtr, nil, fmt.Errorf(
							"No copied child block found for ptr %v",
							iptr.BlockPointer)
					}
					err = fd.tree.cacher(ctx, newPtr, childBlock)
					if err != nil {
						return ZeroPtr, nil, err
					}
				}
			}
		}
	}

	// Finally, make a new ID for the top block and cache it.
	newTopPtr = fd.rootBlockPointer()
	newID, err := kbfsblock.MakeTemporaryID()
	if err != nil {
		return ZeroPtr, nil, err
	}
	newTopPtr = BlockPointer{
		ID:      newID,
		KeyGen:  fd.tree.kmd.LatestKeyGeneration(),
		DataVer: dataVer,
		Context: kbfsblock.MakeFirstContext(
			fd.tree.chargedTo, fd.rootBlockPointer().GetBlockType()),
		DirectType: IndirectBlock,
	}
	fd.tree.vlog.CLogf(
		ctx, libkb.VLog1, "Deep copied indirect file %s: %v -> %v",
		fd.tree.file.TailName(), fd.rootBlockPointer(), newTopPtr)

	newTopBlock, ok := copiedBlocks[fd.rootBlockPointer()]
	if !ok {
		return ZeroPtr, nil, fmt.Errorf(
			"No copied root block found for ptr %v",
			fd.rootBlockPointer())
	}
	if err = fd.tree.cacher(ctx, newTopPtr, newTopBlock); err != nil {
		return ZeroPtr, nil, err
	}

	return newTopPtr, allChildPtrs, nil
}
560598
func (in *BuildSpec) DeepCopy() *BuildSpec {
	if in == nil {
		return nil
	}
	out := new(BuildSpec)
	in.DeepCopyInto(out)
	return out
}
558259
func (in *TemplateInstanceRequester) DeepCopy() *TemplateInstanceRequester {
	if in == nil {
		return nil
	}
	out := new(TemplateInstanceRequester)
	in.DeepCopyInto(out)
	return out
}
556067
func (in *Buffering) DeepCopy() *Buffering {
	if in == nil {
		return nil
	}
	out := new(Buffering)
	in.DeepCopyInto(out)
	return out
}
737726
func (in *BuildStatusOutput) DeepCopy() *BuildStatusOutput {
	if in == nil {
		return nil
	}
	out := new(BuildStatusOutput)
	in.DeepCopyInto(out)
	return out
}
319694
func (in *DebuggingConfiguration) DeepCopy() *DebuggingConfiguration {
	if in == nil {
		return nil
	}
	out := new(DebuggingConfiguration)
	in.DeepCopyInto(out)
	return out
}
451533
func (in *ImageSourcePath) DeepCopy() *ImageSourcePath {
	if in == nil {
		return nil
	}
	out := new(ImageSourcePath)
	in.DeepCopyInto(out)
	return out
}
81605
func (in *GetOptions) DeepCopy() *GetOptions {
	if in == nil {
		return nil
	}
	out := new(GetOptions)
	in.DeepCopyInto(out)
	return out
}
707197
func (in *ClusterRoleBinding) DeepCopy() *ClusterRoleBinding {
	if in == nil {
		return nil
	}
	out := new(ClusterRoleBinding)
	in.DeepCopyInto(out)
	return out
}
479272
func (in *ResourceNode) DeepCopy() *ResourceNode {
	if in == nil {
		return nil
	}
	out := new(ResourceNode)
	in.DeepCopyInto(out)
	return out
}
315326
func (in Rules) DeepCopy() Rules {
	if in == nil {
		return nil
	}
	out := new(Rules)
	in.DeepCopyInto(out)
	return *out
}
921021
func (in *Rule) DeepCopy() *Rule {
	if in == nil {
		return nil
	}
	out := new(Rule)
	in.DeepCopyInto(out)
	return out
}
599208
func (in *IPBlock) DeepCopy() *IPBlock {
	if in == nil {
		return nil
	}
	out := new(IPBlock)
	in.DeepCopyInto(out)
	return out
}
782507
func (in *NodeElement) DeepCopy() *NodeElement {
	if in == nil {
		return nil
	}
	out := new(NodeElement)
	in.DeepCopyInto(out)
	return out
}
445441
func (in *ContinueOn) DeepCopy() *ContinueOn {
	if in == nil {
		return nil
	}
	out := new(ContinueOn)
	in.DeepCopyInto(out)
	return out
}
1148816
func (in *Arguments) DeepCopy() *Arguments {
	if in == nil {
		return nil
	}
	out := new(Arguments)
	in.DeepCopyInto(out)
	return out
}
726296
func (in *Compress) DeepCopy() *Compress {
	if in == nil {
		return nil
	}
	out := new(Compress)
	in.DeepCopyInto(out)
	return out
}