// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package path

import (
	"fmt"

	"android.googlesource.com/platform/tools/gpu/binary"
)

// Capture is a path that refers to a capture.
type Capture struct {
	binary.Generate
	ID binary.ID // The capture's unique identifier.
}

// String returns the string representation of the path.
func (c *Capture) String() string { return c.Path() }

// Path implements the Path interface.
func (c *Capture) Path() string {
	return fmt.Sprintf("Capture(%v)", c.ID)
}

// Base implements the Path interface, returning nil as this is a root.
func (c *Capture) Base() Path {
	return nil
}

// Clone implements the Path interface, returning a deep-copy of this path.
func (c *Capture) Clone() Path {
	return &Capture{ID: c.ID}
}

// Validate implements the Path interface.
func (c *Capture) Validate() error {
	switch {
	case c == nil:
		return fmt.Errorf("Capture is nil")
	case !c.ID.Valid():
		return fmt.Errorf("Capture.ID is invalid")
	}
	return nil
}

// Atoms returns the path to the full list of atoms in the capture.
func (c *Capture) Atoms() *Atoms {
	return &Atoms{Capture: c}
}

// Report returns the path to the capture's report.
func (c *Capture) Report() *Report {
	return &Report{Capture: c}
}

// Hierarchy returns the path to the capture's hierarchy.
func (c *Capture) Hierarchy() *Hierarchy {
	return &Hierarchy{Capture: c}
}

// FindCapture returns the first Capture found traversing the path p.
// If no Capture was found, then nil is returned.
func FindCapture(p Path) *Capture {
	for p != nil {
		if p, ok := p.(*Capture); ok {
			return p
		}
		p = p.Base()
	}
	return nil
}
