package SPVM::Builder::Config::Exe;

use strict;
use warnings;
use Carp 'confess';

use SPVM::Builder::Util;
use SPVM::Builder::Util::API;

# Inheritance
use base 'SPVM::Builder::Config';

# Fields
sub before_each_compile_cbs {
  my $self = shift;
  if (@_) {
    $self->{before_each_compile_cbs} = $_[0];
    return $self;
  }
  else {
    return $self->{before_each_compile_cbs};
  }
}

sub config_spvm_core {
  my $self = shift;
  if (@_) {
    $self->{config_spvm_core} = $_[0];
    return $self;
  }
  else {
    return $self->{config_spvm_core};
  }
}

sub config_bootstrap {
  my $self = shift;
  if (@_) {
    $self->{config_bootstrap} = $_[0];
    return $self;
  }
  else {
    return $self->{config_bootstrap};
  }
}

# Class Methods
sub new {
  my $self = shift;
  
  my %fields = (
    output_type => 'exe',
    before_each_compile_cbs => [],
    config_spvm_core => SPVM::Builder::Util::API::create_default_config(),
    config_bootstrap => SPVM::Builder::Util::API::create_default_config(),
    @_,
  );
  
  $self = $self->SUPER::new(%fields);
  
  return $self;
}

# Instance Methods
sub add_before_each_compile_cb {
  my ($self, @before_each_compile_cbs) = @_;
  
  push @{$self->{before_each_compile_cbs}}, @before_each_compile_cbs;
}

1;

=head1 Name

SPVM::Builder::Config::Exe - Excutable File Config Generated by The spvmcc Command.

=head1 Description

The SPVM::Builder::Config::Exe class has methods to manipulate the excutable file config generated by the L<spvmcc> command.

=head1 Usage

  use SPVM::Builder::Config::Exe;
  
  my $config_exe = SPVM::Builder::Config::Exe->new_gnu99;

=head1 Inheritance

=over 2

=item * L<SPVM::Builder::Config>

=back

=head1 Fields

=head2 before_each_compile_cbs

  my $before_each_compile_cbs = $config_exe->before_each_compile_cbs;
  $config_exe->before_each_compile_cbs($before_each_compile_cbs);

Gets and sets the C<before_each_compile_cbs> field, an array reference of callbacks called just before the compile command L</"cc"> is executed.

This affects all compilations except for SPVM core source files(This is configured by the L</"config_spvm_core"> field) and the source file for the executable file(This is configured by the L</"config_bootstrap"> field).

=head2 config_spvm_core

  my $config_exe_spvm_core = $config_exe->config_spvm_core;
  $config_exe->config_spvm_core($config_exe_spvm_core);

Gets and sets the C<config_spvm_core> field, a L<SPVM::Builder::Config> object for SPVM core source files.

=head2 config_bootstrap

  my $config_exe_bootstrap = $config_exe->config_bootstrap;
  $config_exe->config_bootstrap($config_exe_bootstrap);

Gets and sets the C<config_bootstrap> field, a L<SPVM::Builder::Config> object for the bootstrap source file for the executable file.

=head1 Methods

=head2 new

  my $config_exe = SPVM::Builder::Config::Exe->new(%fields);

Create a new L<SPVM::Builder::Config::Exe> object with L</"Fields">.

This method calls the C<new> method of the L<super class|/"Inheritance"> after default value settings.

If a field is not defined, the field is set to the following default value.

=over 2

=item * L<output_type|SPVM::Builder::Config/"output_type">

"exe"

=item * L</"before_each_compile_cbs">

[]

=item * L</"config_spvm_core">

The return value of the L<create_default_config|SPVM::Builder::Util::API/"create_default_config"> function of the SPVM::Builder::Util::API class.

=item * L</"config_bootstrap">

The return value of the L<create_default_config|SPVM::Builder::Util::API/"create_default_config"> function of the SPVM::Builder::Util::API class.

=back

=head2 add_before_each_compile_cb

  $config_exe->add_before_each_compile_cb(@before_each_compile_cbs);

Adds callbacks called just before the compile command L</"cc"> is executed at the end of the L</"before_each_compile_cbs"> field.

Examples:

  $config_exe->add_before_each_compile_cb(sub {
    my ($config, $compile_info) = @_;
    
    my $cc = $compile_info->cc;
    
    # Do something
  });

=head1 Copyright & License

Copyright (c) 2023 Yuki Kimoto

MIT License
