package Client;
use strict;
use Labels;
use Util;
use Util::Http;

use vars qw($HEADER_DONE);

sub invalid_page {
  my($class) = @_;

  print $class->error("text", 101, 
  "<h1>Invalid Request</h1><br>
   The requested URL is invalid<br>
  <hr><br>
  $ENV{SERVER_SIGNATURE}<br>
  ");

}

sub error {
  my($class, $format, $no, $v) = @_;

  my $out;
  if (!$HEADER_DONE) {
    $HEADER_DONE=1;
    $out .= "HTTP/1.0 200 OK\n" if (!$ENV{FCGI} && !$Http::CGI);
    $out .= "Content-type: text/html\n\n";
  }

  if ($format eq "xml") {
     $out .= "<ERROR no=\"$no\">";
     $out .= Client->xmlEncode($v);
     $out .= "\n</ERROR>\n";
  } else {
     $out .= "#ERROR\t$no\t$v\n";
  }
  return $out;
}

sub errno {
  my($class, $no, $args, $opts) =  @_;

  my $format = $opts->{format} || "xml";
  my $locale = $opts->{locale} || "en";
  my $resource = Labels->read("Client");

  my $msg = $resource->info($no, @$args);

  my $out;
  if (!$HEADER_DONE) {
    $HEADER_DONE=1;
	 $out .= "HTTP/1.0 200 OK\n" if (!$ENV{FCGI} && !$Http::CGI);
    $out .= "Content-type: text/html\n\n";
  }
  if ($format eq "xml") {
     $out .= "<ERROR no=\"$no\" ";
	  my $index;
	  for ($index = 0; $index <= $#$args; $index++){
		 $out .= "arg".($index+1)."=\"";
		 $out .= $args->[$index];
		 $out .= "\" ";
	  }
	  $out .= ">";
     $out .= Client->xmlEncode($msg);
     $out .= "\n</ERROR>\n";
  } else {
     $out .= "#ERROR\t$no\t$msg\n";
  }
  return $out;
}

sub remoteCallKey {
  my ($class, $key, $devs, $cmd, $args) = @_;
  foreach my $d (@$devs) {
	 if ($key eq $d->{key}){
		if ($d->{host}){
		  Client->remoteCall($d->{host}, $cmd, $args);
		  return "1";
		}
	 }
  }
  return undef;
}

sub remoteCall {
  my ($class, $host, $cmd, $args) = @_;

  my $astr;
  for my $arg ( keys %$args ){
	 next if ($arg eq "GO");
	 $astr .= "&" . $arg . "=" . Util->encode($args->{$arg});
  }
  my $cmd2 = $cmd . $astr;
  my ($err, $text) = Util::Http->goCommand($host, $cmd2, 15, undef);
  my $format = $args->{format} || "xml";

  if ($err){
	 Debug->logLine("remote cmd error:".$err);
	 print Client->error($format, 208, $err);
  }else {
	 print Client->http_OK();
	 print "$text\n";
  }
}

sub http_OK {
  my($class)= @_;

  my $out;
  if (!$HEADER_DONE) {
    $out .= "HTTP/1.0 200 OK\n" if (!$ENV{FCGI} && !$Http::CGI);
    $out .= "Content-type: text/html\n\n";
    $HEADER_DONE=1;
  }
  return $out;
}

sub httpHeader {
  my($class, $header, $code)= @_;
  if (!$header){
	 $header = "Content-type: text/html\n";
  }
  if (!$code){
	 $code = "200 OK";
  }
  my $out;
  if (!$HEADER_DONE) {
    $out .= "HTTP/1.0 $code\n" if (!$ENV{FCGI} && !$Http::CGI);
    $out .= $header;
	 $out .= "\n";
    $HEADER_DONE=1;
  }
  return $out;
}

sub xmlHeader {
  return "<?xml version=\"1.0\"?>\n";
}

sub xmlEncode {
  my($class, $value) = @_;

  my $ret = $value;
  $ret =~ s/&/&amp;/g;
  $ret =~ s/</&lt;/g;
  $ret =~ s/>/&gt;/g;
  $ret =~ s/"/&quot;/g;
  $ret =~ s/'/&apos;/g;

  # see unicode characters at: 
  # http://www.unicode.org/Public/MAPPINGS/ETSI/GSM0338.TXT 
  # remove xml invalid unicode such as 0x5. 
  # stop at 0009
  # do not include the new line (000a)
  $ret =~ s/[\x01-\x09]//g;

  #Remove <NUL> - (hex \x00) characters.
  $ret =~ s/\x00//g;

  # remove ESCAPE 
  $ret =~ s/[\x1b]//g;
  return $ret;
}

sub xmlAttrib {
   my($class, $attrib, $value) = @_;
   if ($value){
     return $attrib . "='" . Client->xmlEncode($value) . "' ";
   }
   else {
     return "";
   }
}

sub xmlTagOpen {
  my($class, $tag) = @_;
  return "<" . $tag . "\n";
}

sub xmlTagClose {
  return ">\n";
}

sub xmlTag {
  my($class, $tag) = @_;
  return "<" . $tag . ">\n";
}

sub xmlEndTag {
  my($class, $tag) = @_;
  return "</" . $tag . ">\n";
}

sub xmlVALUE {
  my ($class, $name, $value) = @_;
  if ($value){
    my $out;

    $out .= "<VALUE ID='";
    $out .= $name;
    $out .= "'>";
    $out .= Client->xmlEncode($value);
    $out .= "</VALUE>\n";

    return $out;
  }
  return "";
}

sub xmlCDATA {
  my ($class, $name, $value) = @_;
  if ($value){
    my $out;

    $out .= "<";
    $out .= $name;
    $out .= ">";
    $out .= Client->xmlEncode($value);
    $out .= "</";
	 $out .= $name;
	 $out .= ">\n";

    return $out;
  }
  return "";
}

# [ {hash1}, {hash2} ... ]

sub xmlHashList {
  my($class, $name, $hashList) = @_;
  my $out;
  foreach my $e (@$hashList) {
     $out .= "  <$name>\n";
     foreach my $el (sort keys %$e) {
        $out .= "    <$el>$e->{$el}</$el>\n";
     }
     $out .= "  </$name>\n";
  }
  return $out;
}

1;
