# Copyright 2017 The Bazel Authors. All rights reserved.
#
# 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.

import gzip
import io
import os
import socket
import threading
import unittest
from src.test.py.bazel import test_base

# pylint: disable=g-import-not-at-top,g-importing-member
try:
  from BaseHTTPServer import BaseHTTPRequestHandler
except ImportError:
  from http.server import BaseHTTPRequestHandler

# pylint: disable=g-import-not-at-top,g-importing-member
try:
  from BaseHTTPServer import HTTPServer
except ImportError:
  from http.server import HTTPServer


class MemoryStorageHandler(BaseHTTPRequestHandler):
  protocol_version = 'HTTP/1.1'

  def __init__(self, request, client_address, server):
    BaseHTTPRequestHandler.__init__(self, request, client_address, server)

  def do_PUT(self):
    self.send_response(200)
    self.end_headers()
    self.server.storage[self.path] = self.rfile.read(
        int(self.headers['Content-Length']))
    self.finish()

  def do_GET(self):
    if self.path in self.server.storage and 'gzip' in self.headers[
        'Accept-Encoding']:
      out = io.BytesIO()
      with gzip.GzipFile(fileobj=out, mode='w') as f:
        f.write(self.server.storage[self.path])
      self.send_response(200)
      self.send_header('Content-Length', str(len(out.getvalue())))
      self.send_header('Content-Encoding', 'gzip')
      self.end_headers()
      self.wfile.write(out.getvalue())

    else:
      self.send_response(404)
      self.end_headers()
    self.finish()


class CacheDecompressionTest(test_base.TestBase):

  def setUp(self):
    test_base.TestBase.setUp(self)
    server_port = self.GetFreeTCPPort()
    self.httpd = HTTPServer(('localhost', server_port), MemoryStorageHandler)
    self.httpd.storage = {}
    self.url = 'http://localhost:{}'.format(server_port)
    self.background = threading.Thread(target=self.httpd.serve_forever)
    self.background.start()

  def tearDown(self):
    self.httpd.shutdown()
    self.background.join()
    test_base.TestBase.tearDown(self)

  def testDecompressionWorks(self):
    content = ['Hello HTTP']
    self.ScratchFile('WORKSPACE')
    self.ScratchFile('input.txt', content)
    self.ScratchFile('BUILD', [
        'genrule(',
        '    name = "genrule",',
        '    cmd = "cp \\"$<\\" \\"$@\\"",',
        '    srcs = ["//:input.txt"],',
        '    outs = ["genrule.txt"],',
        ')',
    ])

    exit_code, _, stderr = self.RunBazel(
        ['build', '//:genrule.txt', '--remote_cache', self.url])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertNotIn('INFO: 2 processes: 1 remote cache hit, 1 internal',
                     stderr)
    self.assertNotIn('HTTP version 1.1 is required', stderr)

    exit_code, _, stderr = self.RunBazel(['clean', '--expunge'])
    self.AssertExitCode(exit_code, 0, stderr)

    exit_code, _, stderr = self.RunBazel(
        ['build', '//:genrule.txt', '--remote_cache', self.url])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertIn('INFO: 2 processes: 1 remote cache hit, 1 internal.', stderr)
    self.assertNotIn('HTTP version 1.1 is required', stderr)

    exit_code, stdout, stderr = self.RunBazel(['info', 'bazel-genfiles'])
    self.AssertExitCode(exit_code, 0, stderr)
    bazel_genfiles = stdout[0]

    self.AssertFileContentEqual(
        os.path.join(bazel_genfiles, 'genrule.txt'), content)

  def GetFreeTCPPort(self):
    tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp.bind(('localhost', 0))
    _, port = tcp.getsockname()
    tcp.close()
    return port

  def AssertFileContentEqual(self, file_path, entry):
    with open(file_path, 'r') as f:
      self.assertEqual(f.read().splitlines(), entry)


if __name__ == '__main__':
  unittest.main()
