// 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/transform/emit_vertex_point_size.h"

#include <memory>
#include <utility>

#include "src/ast/assignment_statement.h"
#include "src/ast/block_statement.h"
#include "src/ast/clone_context.h"
#include "src/ast/float_literal.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/scalar_constructor_expression.h"
#include "src/ast/variable.h"
#include "src/type/f32_type.h"
#include "src/type/type_manager.h"

namespace tint {
namespace transform {
namespace {

const char kPointSizeVar[] = "tint_pointsize";

}  // namespace

EmitVertexPointSize::EmitVertexPointSize() = default;
EmitVertexPointSize::~EmitVertexPointSize() = default;

Transform::Output EmitVertexPointSize::Run(ast::Module* in) {
  Output out;

  if (!in->HasStage(ast::PipelineStage::kVertex)) {
    // If the module doesn't have any vertex stages, then there's nothing to do.
    out.module = in->Clone();
    return out;
  }

  auto* f32 = out.module.create<type::F32>();

  // Declare the pointsize builtin output variable.
  auto* pointsize_var = out.module.create<ast::Variable>(
      Source{},                                  // source
      out.module.RegisterSymbol(kPointSizeVar),  // symbol
      ast::StorageClass::kOutput,                // storage_class
      f32,                                       // type
      false,                                     // is_const
      nullptr,                                   // constructor
      ast::VariableDecorationList{
          // decorations
          out.module.create<ast::BuiltinDecoration>(Source{},
                                                    ast::Builtin::kPointSize),
      });
  out.module.AddGlobalVariable(pointsize_var);

  // Build the AST expression & statement for assigning pointsize one.
  auto* one = out.module.create<ast::ScalarConstructorExpression>(
      Source{}, out.module.create<ast::FloatLiteral>(Source{}, f32, 1.0f));
  auto* pointsize_ident = out.module.create<ast::IdentifierExpression>(
      Source{}, out.module.RegisterSymbol(kPointSizeVar));
  auto* pointsize_assign = out.module.create<ast::AssignmentStatement>(
      Source{}, pointsize_ident, one);

  // Add the pointsize assignment statement to the front of all vertex stages.
  ast::CloneContext(&out.module, in)
      .ReplaceAll(
          [&](ast::CloneContext* ctx, ast::Function* func) -> ast::Function* {
            if (func->pipeline_stage() != ast::PipelineStage::kVertex) {
              return nullptr;  // Just clone func
            }
            return CloneWithStatementsAtStart(ctx, func, {pointsize_assign});
          })
      .Clone();

  return out;
}

}  // namespace transform
}  // namespace tint
