// Copyright 2020 The Tint Authors.
//
// 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.

#include "src/reader/spirv/usage.h"

#include <sstream>

namespace tint {
namespace reader {
namespace spirv {

Usage::Usage() {}
Usage::Usage(const Usage& other) = default;
Usage::~Usage() = default;

std::ostream& Usage::operator<<(std::ostream& out) const {
  out << "Usage(";
  if (IsSampler()) {
    out << "Sampler(";
    if (is_comparison_sampler_) {
      out << " comparison";
    }
    out << " )";
  }
  if (IsTexture()) {
    out << "Texture(";
    if (is_sampled_) {
      out << " is_sampled";
    }
    if (is_multisampled_) {
      out << " ms";
    }
    if (is_depth_) {
      out << " depth";
    }
    if (is_storage_read_) {
      out << " read";
    }
    if (is_storage_write_) {
      out << " write";
    }
    out << " )";
  }
  out << ")";
  return out;
}

bool Usage::IsValid() const {
  // Check sampler state internal consistency.
  if (is_comparison_sampler_ && !is_sampler_) {
    return false;
  }

  // Check texture state.
  // |is_texture_| is implied by any of the later texture-based properties.
  if ((IsStorageTexture() || is_sampled_ || is_multisampled_ || is_depth_) &&
      !is_texture_) {
    return false;
  }
  if (is_texture_) {
    // Multisampled implies sampled.
    if (is_multisampled_) {
      if (!is_sampled_) {
        return false;
      }
    }
    // Depth implies sampled.
    if (is_depth_) {
      if (!is_sampled_) {
        return false;
      }
    }

    // Sampled can't be storage.
    if (is_sampled_) {
      if (IsStorageTexture()) {
        return false;
      }
    }

    // Storage can't be sampled.
    if (IsStorageTexture()) {
      if (is_sampled_) {
        return false;
      }
    }
    // Storage texture can't also be a sampler.
    if (IsStorageTexture()) {
      if (is_sampler_) {
        return false;
      }
    }

    // Can't be both read and write.  This is a restriction in WebGPU.
    if (is_storage_read_ && is_storage_write_) {
      return false;
    }
  }
  return true;
}

bool Usage::IsComplete() const {
  if (!IsValid()) {
    return false;
  }
  if (IsSampler()) {
    return true;
  }
  if (IsTexture()) {
    return is_sampled_ || IsStorageTexture();
  }
  return false;
}

bool Usage::operator==(const Usage& other) const {
  return is_sampler_ == other.is_sampler_ &&
         is_comparison_sampler_ == other.is_comparison_sampler_ &&
         is_texture_ == other.is_texture_ && is_sampled_ == other.is_sampled_ &&
         is_multisampled_ == other.is_multisampled_ &&
         is_depth_ == other.is_depth_ &&
         is_storage_read_ == other.is_storage_read_ &&
         is_storage_write_ == other.is_storage_write_;
}

void Usage::Add(const Usage& other) {
  is_sampler_ = is_sampler_ || other.is_sampler_;
  is_comparison_sampler_ =
      is_comparison_sampler_ || other.is_comparison_sampler_;
  is_texture_ = is_texture_ || other.is_texture_;
  is_sampled_ = is_sampled_ || other.is_sampled_;
  is_multisampled_ = is_multisampled_ || other.is_multisampled_;
  is_depth_ = is_depth_ || other.is_depth_;
  is_storage_read_ = is_storage_read_ || other.is_storage_read_;
  is_storage_write_ = is_storage_write_ || other.is_storage_write_;
}

void Usage::AddSampler() {
  is_sampler_ = true;
}

void Usage::AddComparisonSampler() {
  AddSampler();
  is_comparison_sampler_ = true;
}

void Usage::AddTexture() {
  is_texture_ = true;
}

void Usage::AddStorageReadTexture() {
  AddTexture();
  is_storage_read_ = true;
}

void Usage::AddStorageWriteTexture() {
  AddTexture();
  is_storage_write_ = true;
}

void Usage::AddSampledTexture() {
  AddTexture();
  is_sampled_ = true;
}

void Usage::AddMultisampledTexture() {
  AddSampledTexture();
  is_multisampled_ = true;
}

void Usage::AddDepthTexture() {
  AddSampledTexture();
  is_depth_ = true;
}

std::string Usage::to_str() const {
  std::ostringstream ss;
  ss << *this;
  return ss.str();
}

}  // namespace spirv
}  // namespace reader
}  // namespace tint
