#!/usr/bin/env perl

use FindBin '$Bin';

use common::sense;

use Getopt::Long;
use JSON;
use Tie::IxHash;

my $CONF_PATH     = "$Bin/../conf/providers.json";
my $SPRITE_FORMAT = '//yandex.st/social/current/sprites/%iconsize%.png';
tie my %SPRITE_SIZES, 'Tie::IxHash', qw/16 ico-16 19 ico-19 24 ico-24 32 ico-32 64 ico-64 full logo/;
my $ICON_FORMAT   = '//yandex.st/social/current/icons/%iconsize%/%provider%.png';
my $URL_FORMAT    = 'https://%host%/broker/start?provider=%provider%&action_if_anonymous=authorize&display=%display%&popupName=social_bar&consumer=bar&result_location=fragment&retpath=%retpath%';
my $RETPATH       = 'https%3A%2F%2Fsocial.yandex.ru%2Fhtml%2Fcloser%2Fpromo_closer.html%23ddom%3D';

my %FLAT_ICON_SPRITES;
tie my %FLAT_ICON_SPRITES, 'Tie::IxHash';
%FLAT_ICON_SPRITES = (
    'flat44'  => '//yastatic.net/broker/1.8/img/social-flat-44.png',
    'flat66'  => '//yastatic.net/broker/1.8/img/social-flat-66.png',
    'flat88'  => '//yastatic.net/broker/1.8/img/social-flat-88.png',
    'flat132' => '//yastatic.net/broker/1.8/img/social-flat-132.png',
);

my ($format, $iconsize, $display, @filter_providers, @primary_values, $lang, $version, $host);
GetOptions(
    'format=s'   => \$format,
    'iconsize=s' => \$iconsize,
    'display=s'  => \$display,
    'providers=s{,}' => \@filter_providers,
    'primary=i{,}'   => \@primary_values,
    'lang=s'      => \$lang,
    'version=i'   => \$version,
    'host=s',     => \$host,
);
die "format is required"
  unless $format =~ /^ (?: xml | jsonp? ) $/x;

$lang    ||= 'default';
$version ||= 1;
$host    ||= 'social.yandex.ru';

my %filter_providers;
$filter_providers{ $filter_providers[$_] } = $_
  for 0 .. $#filter_providers;

my $conf_json = do { local(@ARGV, $/) = $CONF_PATH; <> };
my $conf_data = decode_json $conf_json;

my @all_providers = @{ $conf_data };
my @sorted_providers = sort { $a->{id} <=> $b->{id} } @all_providers;

my @providers;
for my $provider (@sorted_providers) {
    my $filter_index = $filter_providers{$provider->{code}};
    next unless defined $filter_index;
    tie my %item, 'Tie::IxHash';
    %item = (
        primary      => $primary_values[$filter_index] ? JSON::true : JSON::false,
        name         => $provider->{name},
        id           => $provider->{id} + 0,
        display_name => $provider->{display_name}{$lang} || $provider->{display_name}{default},
        enabled      => $provider->{allow_auth}        ? JSON::true : JSON::false,
        code         => $provider->{code},
    );
    push @providers, \%item;
}

my $result;

my $data;
if ($format =~ /json/) {
    if ($version eq 1) {
        $data = \@providers;
    }
    elsif ($version eq 2) {
        tie my %icon_sprites, 'Tie::IxHash';
        for my $iconsize (keys %SPRITE_SIZES) {
            my $iconsize_name = $SPRITE_SIZES{$iconsize};
            my $url = $SPRITE_FORMAT;
            $url =~ s/%iconsize%/$iconsize_name/;
            $icon_sprites{$iconsize} = $url;
        }
        %icon_sprites = (
            %icon_sprites,
            %FLAT_ICON_SPRITES,
        );
        $data = {
            providers    => \@providers,
            icon_sprites => \%icon_sprites,
        };
    }
}

given ($format) {
    when ('json')  {
        $result .= encode_json $data;
    }
    when ('jsonp') {
        $result .= "/**/\n";
        $result .= 'try { ';
        $result .= '%%callback%%(';
        $result .= encode_json $data;
        $result .= '); } catch (e) {}';
    }
    when ('xml')   {
        $result .= qq/<?xml version="1.0" encoding="utf-8"?>\n/;
        $result .= "<providers>\n";

        for my $provider (@providers) {
            my $string
              = sprintf qq(  <provider id="%d" code="%s" enabled="%d" primary="%d" display_name="%s"),
              $provider->{id}, $provider->{code}, $provider->{enabled}, $provider->{primary}, $provider->{display_name};

            if ($iconsize and $display) {
                my $retpath = $RETPATH;
                $string .= sprintf qq( icon="http:%s" url="%s"), $ICON_FORMAT, $URL_FORMAT;
                $string =~ s/%host%/$host/g;
                $string =~ s/%provider%/$provider->{code}/g;
                $string =~ s/%display%/$display/g;
                $string =~ s/%iconsize%/$iconsize/g;
                $string =~ s/%retpath%/$retpath/g;
                $string =~ s/&/&amp;/g;
            }

            $string .= " />\n";
            $result .= $string;
        }

        $result .= "</providers>";
    }
}

say $result;
