#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;

# Ensure UTF-8 output to avoid wide character warnings
use open qw(:std :encoding(UTF-8));

# Usage: ./merge.pl file1.xml file2.xml … > combined.xml

my %seen_channel;
my @channels;
my @programmes;
my %tv_attrs;
my $got_tv = 0;

# Create a Twig parser to collect data
my $twig = XML::Twig->new(
  pretty_print        => 'indented',
  start_tag_handlers  => {
    'tv' => sub {
      my ($t, $elt) = @_;
      return if $got_tv;
      # Capture the first <tv> attributes
      for my $attr ($elt->att_names) {
        $tv_attrs{$attr} = $elt->att($attr);
      }
      $got_tv = 1;
    },
  },
  twig_handlers       => {
    'channel' => sub {
      my ($t, $elt) = @_;
      my $id = $elt->att('id') // '';
      unless ($seen_channel{$id}++) {
        push @channels, $elt->copy;
      }
      $elt->purge;
    },
    'programme' => sub {
      my ($t, $elt) = @_;
      push @programmes, $elt->copy;
      $elt->purge;
    },
  },
);

# Parse each input file, but skip any that are empty
foreach my $file (@ARGV) {
    # Skip if this is the final output file itself
    if ( $file eq 'combined.xml' ) {
        warn "Skipping output file '$file'\n";
        next;
    }
    if ( -z $file ) {
        warn "Skipping empty file '$file'\n";
        next;
    }
    eval { $twig->parsefile($file) };
    die "Error parsing '$file': $@" if $@;
}

# Build merged <tv> element
my $tv = XML::Twig::Elt->new('tv');
# Set attributes
$tv->set_att($_ => $tv_attrs{$_}) for keys %tv_attrs;

# Append channels and programmes
for my $chan (@channels) {
    $chan->paste(last_child => $tv);
}
for my $prog (@programmes) {
    $prog->paste(last_child => $tv);
}

# Output
print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
print $tv->sprint;
