=head1 LICENSE

Copyright [2016-2023] EMBL-European Bioinformatics Institute

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.

=cut


=head1 CONTACT

 Please email comments or questions to the public Ensembl
 developers list at <http://lists.ensembl.org/mailman/listinfo/dev>.

 Questions may also be sent to the Ensembl help desk at
 <http://www.ensembl.org/Help/Contact>.

=cut

# EnsEMBL module for Bio::EnsEMBL::VEP::OutputFactory::Tab
#
#

=head1 NAME

Bio::EnsEMBL::VEP::OutputFactory::Tab - Tab-delimited format output factory

=head1 SYNOPSIS

my $of = Bio::EnsEMBL::VEP::OutputFactory::Tab->new({
  config => $config,
});

# print headers
print "$_\n" for @{$of->headers};

# print output
print "$_\n" for @{$of->get_all_lines_by_InputBuffer($ib)};

=head1 DESCRIPTION

An OutputFactory class to generate tab-delimited output, with
one column per output field. Fields will vary according to
selected options and/or user configuration (with --fields).

Similar to VEP_output, this is a tab-delimited format designed
to present one line of data per VariationFeatureOverlapAllele
object (i.e. one line per variant allele/feature combination).

The class shares a base class with
Bio::EnsEMBL::VEP::OutputFactory::VEP_output as there are several
methods that are shared between the two (but not with other
sub-classes of OutputFactory).

=head1 METHODS

=cut


use strict;
use warnings;

package Bio::EnsEMBL::VEP::OutputFactory::Tab;

use base qw(Bio::EnsEMBL::VEP::OutputFactory::BaseTab);

use Bio::EnsEMBL::VEP::Utils qw(convert_arrayref);
use Bio::EnsEMBL::VEP::Constants;


=head2 new

  Arg 1      : hashref $args
  Example    : $of = Bio::EnsEMBL::VEP::OutputFactory::Tab->new({
                 config => $config,
               });
  Description: Creates a new Bio::EnsEMBL::VEP::OutputFactory::Tab object.
               Has its own constructor to add the "fields" param via
               add_shortcuts()
  Returntype : Bio::EnsEMBL::VEP::OutputFactory::Tab
  Exceptions : none
  Caller     : Runner
  Status     : Stable

=cut

sub new {
  my $caller = shift;
  my $class = ref($caller) || $caller;
  
  my $self = $class->SUPER::new(@_);

  # add shortcuts to these params
  $self->add_shortcuts([qw(
    fields
  )]);

  return $self;
}


=head2 output_hash_to_line

  Arg 1      : hashref $vf_hash
  Example    : $line = $of->output_hash_to_line($vf_hash);
  Description: Takes a hashref as generated by get_all_output_hashes_by_InputBuffer
               and returns a tab-delimited string ready for printing.
  Returntype : string
  Exceptions : none
  Caller     : get_all_lines_by_InputBuffer()
  Status     : Stable

=cut

sub output_hash_to_line {
  my $self = shift;
  my $hash = shift;
  return join("\t", map {defined($hash->{$_}) ? convert_arrayref($hash->{$_}) : '-'} @{$self->fields});
}


=head2 description_headers

  Example    : $headers = $of->description_headers();
  Description: Gets column description headers e.g.
               ## Field1 : description1
  Returntype : arrayref of strings
  Exceptions : none
  Caller     : headers()
  Status     : Stable

=cut

sub description_headers {
  my $self = shift;

  my $field_descs = \%Bio::EnsEMBL::VEP::Constants::FIELD_DESCRIPTIONS;

  my %other_descs = map {$_->[0] => $_->[1]} @{$self->get_plugin_headers}, @{$self->get_custom_headers};

  return [
    '## Column descriptions:',
    map {'## '.$_.' : '.($field_descs->{$_} || $other_descs{$_} || '?')}
    @{$self->fields}
  ];
}


=head2 column_header

  Example    : $header = $of->column_header();
  Description: Gets column header e.g.
               #col1  col2  col3  col4
  Returntype : string
  Exceptions : none
  Caller     : headers()
  Status     : Stable

=cut

sub column_header {
  return '#'.join("\t", @{$_[0]->fields});
}


=head2 fields

  Example    : $fields = $of->fields();
  Description: Gets list of fields to be populated
  Returntype : arrayref of strings
  Exceptions : none
  Caller     : field_order(), 
  Status     : Stable

=cut

sub fields {
  my $self = shift;

  if(!defined($self->{fields})) {

    my @fields = (
      @Bio::EnsEMBL::VEP::Constants::DEFAULT_OUTPUT_COLS,
      @{$self->flag_fields},
      map {$_->[0]} (@{$self->get_plugin_headers}, @{$self->get_custom_headers})
    );
    
    $self->{fields} = \@fields;
  }

  return $self->{fields};
}

1;
