package Net::Connector::Cisco::Ios;

#------------------------------------------------------------------------------
# 加载扩展模块
#------------------------------------------------------------------------------
use 5.016;
use Expect;
use Moose;
use namespace::autoclean;

#------------------------------------------------------------------------------
# 继承 Net::Connector::Role 方法属性,同时具体实现其指定方法
#------------------------------------------------------------------------------
with 'Net::Connector::Role';

#------------------------------------------------------------------------------
# 具体实现 _buildPrompt,设置设备脚本执行成功回显
#------------------------------------------------------------------------------
sub _buildPrompt {
  my $self   = shift;
  my $prompt = '[\w\d\-\_]+\#\s*';
  return $prompt;
}

#------------------------------------------------------------------------------
# 具体实现 _buildCommands,设置抓取设备运行配置的脚本
#------------------------------------------------------------------------------
sub _buildCommands {
  my $self     = shift;
  my $commands = [ "terminal length 0", "show running-config", "copy run start" ];

  # my $commands = ["show running-config"];
  return $commands;
}

#------------------------------------------------------------------------------
# 具体实现 _buildErrorCode,设置命令下发错误码 -> 用于拦截配置下发
#------------------------------------------------------------------------------
sub _buildErrorCode {
  my $self  = shift;
  my $codes = [
    'for a list of subcommands',
    '% Incomplete command',
    '% Ambiguous command',
    '% Permission denied',
    'command authorization failed',
    'Invalid input detected|Type help or ',
    'Line has invalid autocommand',
    'Invalid input detected|Incomplete command',
    'Invalid |\%Error ',
  ];
  return $codes;
}

#------------------------------------------------------------------------------
# 具体实现 _buildBufferCode,设置交互式执行脚本 -> 用于交互式下发配置
#------------------------------------------------------------------------------
sub _buildBufferCode {
  my $self    = shift;
  my %mapping = (
    more     => '--More--',
    interact => {
      '\[startup-config\]\?'              => ' ',
      'Address or name of remote host \[' => "\r",
      'Destination filename \['           => "\r",
      'overwrite\?\s*\[Y\/N\]'            => 'Y',
    }
  );

  # 返回数据字典
  return \%mapping;
}

#------------------------------------------------------------------------------
# 具体实现 runCommands，编写进入特权模式、退出保存配置的逻辑
#------------------------------------------------------------------------------
sub runCommands {
  my ( $self, $commands ) = @_;

  # 用户传递的具体配置 | 需要先初始化配置
  $self->setCommands($commands);

  # 配置下发前 | 切入配置模式
  $self->addCommand('conf t');

  # 完成配置后 | 报错具体配置
  $self->pushCommand("copy run start");

  # 执行调度，配置批量下发
  $self->execCommands( $self->commands->@* );
}

# generate tftp config variables
sub generate_tftp_cmd {

  # load modules
  use Carp;
  use POSIX qw/strftime/;

  my ( $self, $ip, $hostname ) = @_;
  $hostname = $ip unless defined $hostname;
  confess "must provide ip and hostname" if not defined $ip or $ip eq "";

  my $tftp_server = $self->tftp_server;

  # init variables
  my $dir  = strftime( "%Y-%m",  localtime );
  my $time = strftime( "%Y%m%d", localtime );

  # generate tftp path
  my $tftp_destination = $tftp_server . "$dir/$time/$ip-$hostname.config";

  # generate tftp_destination
  return "copy running-config $tftp_destination";
}

# 支持 tftp 保存运行配置
sub copy_config_by_tftp {
  my ( $self, $ip, $hostname ) = @_;

  # 生成命令
  my $cmd = $self->generate_tftp_cmd( $ip, $hostname );

  # 执行脚本
  return $self->execCommands($cmd);

}
__PACKAGE__->meta->make_immutable;
1;
