#! /usr/bin/python
'''
Copyright 2016 Intel Corporation

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.
'''

from cmd import Cmd
import os
import subprocess
import re
import sys
try:
        import readline
except ImportError:
        readline = None

persishist = os.path.expanduser('~/.vpphistory')
persishist_size = 1000
if not persishist:
        os.mknod(persishist, stat.S_IFREG)

class Vppctl(Cmd):

        def historyWrite(self):
                if readline:
                        readline.set_history_length(persishist_size)
                        readline.write_history_file(persishist)

        def runVat(self, line):
                input_prefix = "exec "
                input_command = input_prefix + line
                line_remove = '^load_one_plugin:'
                s = '\n'
                command = ['vpp_api_test']

                if os.geteuid() != 0:
                    command = ['sudo', 'vpp_api_test']

                vpp_process = subprocess.Popen(command,
                        stderr=subprocess.PIPE,
                        stdin=subprocess.PIPE,
                        stdout=subprocess.PIPE)
                stdout_value = vpp_process.communicate(input_command)[0]

                buffer_stdout = stdout_value.splitlines()

                buffer_stdout[:]  = [b for b in buffer_stdout
                        if line_remove not in b]

                for i, num in enumerate(buffer_stdout):
                        buffer_stdout[i] = num.replace('vat# ','')

                stdout_value = s.join(buffer_stdout)
                print stdout_value

        def do_help(self, line):
                self.runVat("help")

        def default(self, line):
                self.runVat(line)

        def do_exit(self, line):
                self.historyWrite()
                raise SystemExit

        def emptyline(self):
                pass

        def do_EOF(self,line):
                self.historyWrite()
                sys.stdout.write('\n')
                raise SystemExit

        def preloop(self):
                if readline and os.path.exists(persishist):
                        readline.read_history_file(persishist)

        def postcmd(self, stop, line):
                self.historyWrite()

if __name__ == '__main__':
        command_args = sys.argv


        if not len(command_args) > 1:
                prompt = Vppctl()
                red_set = '\033[31m'
                norm_set = '\033[0m'
                if sys.stdout.isatty():
                        prompt.prompt = 'vpp# '
                        try:
                                prompt.cmdloop(red_set + "    _______    _       " + norm_set + " _   _____  ___ \n" +
                                        red_set + " __/ __/ _ \  (_)__   " + norm_set + " | | / / _ \/ _ \\\n" +
                                        red_set + " _/ _// // / / / _ \\" + norm_set + "   | |/ / ___/ ___/\n" +
                                        red_set + " /_/ /____(_)_/\___/   " + norm_set + "|___/_/  /_/   \n")
                        except KeyboardInterrupt:
                                sys.stdout.write('\n')
                else:
                        try:
                                prompt.cmdloop()
                        except KeyboardInterrupt:
                                sys.stdout.write('\n')
        else:
                del command_args[0]
                stdout_value = " ".join(command_args)
                VatAddress = Vppctl()
                VatAddress.runVat(stdout_value)



